Merge 5.10.24 into android12-5.10-lts
Changes in 5.10.24 uapi: nfnetlink_cthelper.h: fix userspace compilation error powerpc/perf: Fix handling of privilege level checks in perf interrupt context powerpc/pseries: Don't enforce MSI affinity with kdump ethernet: alx: fix order of calls on resume crypto: mips/poly1305 - enable for all MIPS processors ath9k: fix transmitting to stations in dynamic SMPS mode net: Fix gro aggregation for udp encaps with zero csum net: check if protocol extracted by virtio_net_hdr_set_proto is correct net: avoid infinite loop in mpls_gso_segment when mpls_hlen == 0 net: l2tp: reduce log level of messages in receive path, add counter instead can: skb: can_skb_set_owner(): fix ref counting if socket was closed before setting skb ownership can: flexcan: assert FRZ bit in flexcan_chip_freeze() can: flexcan: enable RX FIFO after FRZ/HALT valid can: flexcan: invoke flexcan_chip_freeze() to enter freeze mode can: tcan4x5x: tcan4x5x_init(): fix initialization - clear MRAM before entering Normal Mode tcp: Fix sign comparison bug in getsockopt(TCP_ZEROCOPY_RECEIVE) tcp: add sanity tests to TCP_QUEUE_SEQ netfilter: nf_nat: undo erroneous tcp edemux lookup netfilter: x_tables: gpf inside xt_find_revision() net: always use icmp{,v6}_ndo_send from ndo_start_xmit net: phy: fix save wrong speed and duplex problem if autoneg is on selftests/bpf: Use the last page in test_snprintf_btf on s390 selftests/bpf: No need to drop the packet when there is no geneve opt selftests/bpf: Mask bpf_csum_diff() return value to 16 bits in test_verifier samples, bpf: Add missing munmap in xdpsock libbpf: Clear map_info before each bpf_obj_get_info_by_fd ibmvnic: Fix possibly uninitialized old_num_tx_queues variable warning. ibmvnic: always store valid MAC address mt76: dma: do not report truncated frames to mac80211 powerpc/603: Fix protection of user pages mapped with PROT_NONE mount: fix mounting of detached mounts onto targets that reside on shared mounts cifs: return proper error code in statfs(2) Revert "mm, slub: consider rest of partial list if acquire_slab() fails" docs: networking: drop special stable handling net: dsa: tag_rtl4_a: fix egress tags sh_eth: fix TRSCER mask for SH771x net: enetc: don't overwrite the RSS indirection table when initializing net: enetc: take the MDIO lock only once per NAPI poll cycle net: enetc: fix incorrect TPID when receiving 802.1ad tagged packets net: enetc: don't disable VLAN filtering in IFF_PROMISC mode net: enetc: force the RGMII speed and duplex instead of operating in inband mode net: enetc: remove bogus write to SIRXIDR from enetc_setup_rxbdr net: enetc: keep RX ring consumer index in sync with hardware net: ethernet: mtk-star-emac: fix wrong unmap in RX handling net/mlx4_en: update moderation when config reset net: stmmac: fix incorrect DMA channel intr enable setting of EQoS v4.10 nexthop: Do not flush blackhole nexthops when loopback goes down net: sched: avoid duplicates in classes dump net: mscc: ocelot: properly reject destination IP keys in VCAP IS1 net: dsa: sja1105: fix SGMII PCS being forced to SPEED_UNKNOWN instead of SPEED_10 net: usb: qmi_wwan: allow qmimux add/del with master up netdevsim: init u64 stats for 32bit hardware cipso,calipso: resolve a number of problems with the DOI refcounts net: stmmac: Fix VLAN filter delete timeout issue in Intel mGBE SGMII stmmac: intel: Fixes clock registration error seen for multiple interfaces net: lapbether: Remove netif_start_queue / netif_stop_queue net: davicom: Fix regulator not turned off on failed probe net: davicom: Fix regulator not turned off on driver removal net: enetc: allow hardware timestamping on TX queues with tc-etf enabled net: qrtr: fix error return code of qrtr_sendmsg() s390/qeth: fix memory leak after failed TX Buffer allocation r8169: fix r8168fp_adjust_ocp_cmd function ixgbe: fail to create xfrm offload of IPsec tunnel mode SA tools/resolve_btfids: Fix build error with older host toolchains perf build: Fix ccache usage in $(CC) when generating arch errno table net: stmmac: stop each tx channel independently net: stmmac: fix watchdog timeout during suspend/resume stress test net: stmmac: fix wrongly set buffer2 valid when sph unsupport ethtool: fix the check logic of at least one channel for RX/TX net: phy: make mdio_bus_phy_suspend/resume as __maybe_unused selftests: forwarding: Fix race condition in mirror installation mlxsw: spectrum_ethtool: Add an external speed to PTYS register perf traceevent: Ensure read cmdlines are null terminated. perf report: Fix -F for branch & mem modes net: hns3: fix query vlan mask value error for flow director net: hns3: fix bug when calculating the TCAM table info s390/cio: return -EFAULT if copy_to_user() fails again bnxt_en: reliably allocate IRQ table on reset to avoid crash gpiolib: acpi: Add ACPI_GPIO_QUIRK_ABSOLUTE_NUMBER quirk gpiolib: acpi: Allow to find GpioInt() resource by name and index gpio: pca953x: Set IRQ type when handle Intel Galileo Gen 2 gpio: fix gpio-device list corruption drm/compat: Clear bounce structures drm/amd/display: Add a backlight module option drm/amdgpu/display: use GFP_ATOMIC in dcn21_validate_bandwidth_fp() drm/amd/display: Fix nested FPU context in dcn21_validate_bandwidth() drm/amd/pm: bug fix for pcie dpm drm/amdgpu/display: simplify backlight setting drm/amdgpu/display: don't assert in set backlight function drm/amdgpu/display: handle aux backlight in backlight_get_brightness drm/shmem-helper: Check for purged buffers in fault handler drm/shmem-helper: Don't remove the offset in vm_area_struct pgoff drm: Use USB controller's DMA mask when importing dmabufs drm: meson_drv add shutdown function drm/shmem-helpers: vunmap: Don't put pages for dma-buf drm/i915: Wedge the GPU if command parser setup fails s390/cio: return -EFAULT if copy_to_user() fails s390/crypto: return -EFAULT if copy_to_user() fails qxl: Fix uninitialised struct field head.surface_id sh_eth: fix TRSCER mask for R7S9210 media: usbtv: Fix deadlock on suspend media: rkisp1: params: fix wrong bits settings media: v4l: vsp1: Fix uif null pointer access media: v4l: vsp1: Fix bru null pointer access media: rc: compile rc-cec.c into rc-core cifs: fix credit accounting for extra channel net: hns3: fix error mask definition of flow director s390/qeth: don't replace a fully completed async TX buffer s390/qeth: remove QETH_QDIO_BUF_HANDLED_DELAYED state s390/qeth: improve completion of pending TX buffers s390/qeth: fix notification for pending buffers during teardown net: dsa: implement a central TX reallocation procedure net: dsa: tag_ksz: don't allocate additional memory for padding/tagging net: dsa: trailer: don't allocate additional memory for padding/tagging net: dsa: tag_qca: let DSA core deal with TX reallocation net: dsa: tag_ocelot: let DSA core deal with TX reallocation net: dsa: tag_mtk: let DSA core deal with TX reallocation net: dsa: tag_lan9303: let DSA core deal with TX reallocation net: dsa: tag_edsa: let DSA core deal with TX reallocation net: dsa: tag_brcm: let DSA core deal with TX reallocation net: dsa: tag_dsa: let DSA core deal with TX reallocation net: dsa: tag_gswip: let DSA core deal with TX reallocation net: dsa: tag_ar9331: let DSA core deal with TX reallocation net: dsa: tag_mtk: fix 802.1ad VLAN egress enetc: Fix unused var build warning for CONFIG_OF net: enetc: initialize RFS/RSS memories for unused ports too ath11k: peer delete synchronization with firmware ath11k: start vdev if a bss peer is already created ath11k: fix AP mode for QCA6390 i2c: rcar: faster irq code to minimize HW race condition i2c: rcar: optimize cacheline to minimize HW race condition scsi: ufs: WB is only available on LUN #0 to #7 udf: fix silent AED tagLocation corruption iommu/vt-d: Clear PRQ overflow only when PRQ is empty mmc: mxs-mmc: Fix a resource leak in an error handling path in 'mxs_mmc_probe()' mmc: mediatek: fix race condition between msdc_request_timeout and irq mmc: sdhci-iproc: Add ACPI bindings for the RPi Platform: OLPC: Fix probe error handling powerpc/pci: Add ppc_md.discover_phbs() spi: stm32: make spurious and overrun interrupts visible powerpc: improve handling of unrecoverable system reset powerpc/perf: Record counter overflow always if SAMPLE_IP is unset HID: logitech-dj: add support for the new lightspeed connection iteration powerpc/64: Fix stack trace not displaying final frame iommu/amd: Fix performance counter initialization clk: qcom: gdsc: Implement NO_RET_PERIPH flag sparc32: Limit memblock allocation to low memory sparc64: Use arch_validate_flags() to validate ADI flag Input: applespi - don't wait for responses to commands indefinitely. PCI: xgene-msi: Fix race in installing chained irq handler PCI: mediatek: Add missing of_node_put() to fix reference leak drivers/base: build kunit tests without structleak plugin PCI/LINK: Remove bandwidth notification ext4: don't try to processed freed blocks until mballoc is initialized kbuild: clamp SUBLEVEL to 255 PCI: Fix pci_register_io_range() memory leak i40e: Fix memory leak in i40e_probe kasan: fix memory corruption in kasan_bitops_tags test s390/smp: __smp_rescan_cpus() - move cpumask away from stack drivers/base/memory: don't store phys_device in memory blocks sysctl.c: fix underflow value setting risk in vm_table scsi: libiscsi: Fix iscsi_prep_scsi_cmd_pdu() error handling scsi: target: core: Add cmd length set before cmd complete scsi: target: core: Prevent underflow for service actions clk: qcom: gpucc-msm8998: Add resets, cxc, fix flags on gpu_gx_gdsc mmc: sdhci: Update firmware interface API ARM: 9029/1: Make iwmmxt.S support Clang's integrated assembler ARM: assembler: introduce adr_l, ldr_l and str_l macros ARM: efistub: replace adrl pseudo-op with adr_l macro invocation ALSA: usb: Add Plantronics C320-M USB ctrl msg delay quirk ALSA: hda/hdmi: Cancel pending works before suspend ALSA: hda/conexant: Add quirk for mute LED control on HP ZBook G5 ALSA: hda/ca0132: Add Sound BlasterX AE-5 Plus support ALSA: hda: Drop the BATCH workaround for AMD controllers ALSA: hda: Flush pending unsolicited events before suspend ALSA: hda: Avoid spurious unsol event handling during S3/S4 ALSA: usb-audio: Fix "cannot get freq eq" errors on Dell AE515 sound bar ALSA: usb-audio: Apply the control quirk to Plantronics headsets ALSA: usb-audio: Disable USB autosuspend properly in setup_disable_autosuspend() ALSA: usb-audio: fix NULL ptr dereference in usb_audio_probe ALSA: usb-audio: fix use after free in usb_audio_disconnect Revert 95ebabde382c ("capabilities: Don't allow writing ambiguous v3 file capabilities") block: Discard page cache of zone reset target range block: Try to handle busy underlying device on discard arm64: kasan: fix page_alloc tagging with DEBUG_VIRTUAL arm64: mte: Map hotplugged memory as Normal Tagged arm64: perf: Fix 64-bit event counter read truncation s390/dasd: fix hanging DASD driver unbind s390/dasd: fix hanging IO request during DASD driver unbind software node: Fix node registration xen/events: reset affinity of 2-level event when tearing it down mmc: mmci: Add MMC_CAP_NEED_RSP_BUSY for the stm32 variants mmc: core: Fix partition switch time for eMMC mmc: cqhci: Fix random crash when remove mmc module/card cifs: do not send close in compound create+close requests Goodix Fingerprint device is not a modem USB: gadget: udc: s3c2410_udc: fix return value check in s3c2410_udc_probe() USB: gadget: u_ether: Fix a configfs return code usb: gadget: f_uac2: always increase endpoint max_packet_size by one audio slot usb: gadget: f_uac1: stop playback on function disable usb: dwc3: qcom: Add missing DWC3 OF node refcount decrement usb: dwc3: qcom: add URS Host support for sdm845 ACPI boot usb: dwc3: qcom: add ACPI device id for sc8180x usb: dwc3: qcom: Honor wakeup enabled/disabled state USB: usblp: fix a hang in poll() if disconnected usb: renesas_usbhs: Clear PIPECFG for re-enabling pipe with other EPNUM usb: xhci: do not perform Soft Retry for some xHCI hosts xhci: Improve detection of device initiated wake signal. usb: xhci: Fix ASMedia ASM1042A and ASM3242 DMA addressing xhci: Fix repeated xhci wake after suspend due to uncleared internal wake state USB: serial: io_edgeport: fix memory leak in edge_startup USB: serial: ch341: add new Product ID USB: serial: cp210x: add ID for Acuity Brands nLight Air Adapter USB: serial: cp210x: add some more GE USB IDs usbip: fix stub_dev to check for stream socket usbip: fix vhci_hcd to check for stream socket usbip: fix vudc to check for stream socket usbip: fix stub_dev usbip_sockfd_store() races leading to gpf usbip: fix vhci_hcd attach_store() races leading to gpf usbip: fix vudc usbip_sockfd_store races leading to gpf Revert "serial: max310x: rework RX interrupt handling" misc/pvpanic: Export module FDT device table misc: fastrpc: restrict user apps from sending kernel RPC messages staging: rtl8192u: fix ->ssid overflow in r8192_wx_set_scan() staging: rtl8188eu: prevent ->ssid overflow in rtw_wx_set_scan() staging: rtl8712: unterminated string leads to read overflow staging: rtl8188eu: fix potential memory corruption in rtw_check_beacon_data() staging: ks7010: prevent buffer overflow in ks_wlan_set_scan() staging: rtl8712: Fix possible buffer overflow in r8712_sitesurvey_cmd staging: rtl8192e: Fix possible buffer overflow in _rtl92e_wx_set_scan staging: comedi: addi_apci_1032: Fix endian problem for COS sample staging: comedi: addi_apci_1500: Fix endian problem for command sample staging: comedi: adv_pci1710: Fix endian problem for AI command data staging: comedi: das6402: Fix endian problem for AI command data staging: comedi: das800: Fix endian problem for AI command data staging: comedi: dmm32at: Fix endian problem for AI command data staging: comedi: me4000: Fix endian problem for AI command data staging: comedi: pcl711: Fix endian problem for AI command data staging: comedi: pcl818: Fix endian problem for AI command data sh_eth: fix TRSCER mask for R7S72100 cpufreq: qcom-hw: fix dereferencing freed memory 'data' cpufreq: qcom-hw: Fix return value check in qcom_cpufreq_hw_cpu_init() arm64/mm: Fix pfn_valid() for ZONE_DEVICE based memory SUNRPC: Set memalloc_nofs_save() for sync tasks NFS: Don't revalidate the directory permissions on a lookup failure NFS: Don't gratuitously clear the inode cache when lookup failed NFSv4.2: fix return value of _nfs4_get_security_label() block: rsxx: fix error return code of rsxx_pci_probe() nvme-fc: fix racing controller reset and create association configfs: fix a use-after-free in __configfs_open_file arm64: mm: use a 48-bit ID map when possible on 52-bit VA builds perf/core: Flush PMU internal buffers for per-CPU events perf/x86/intel: Set PERF_ATTACH_SCHED_CB for large PEBS and LBR hrtimer: Update softirq_expires_next correctly after __hrtimer_get_next_event() powerpc/64s/exception: Clean up a missed SRR specifier seqlock,lockdep: Fix seqcount_latch_init() stop_machine: mark helpers __always_inline include/linux/sched/mm.h: use rcu_dereference in in_vfork() zram: fix return value on writeback_store linux/compiler-clang.h: define HAVE_BUILTIN_BSWAP* sched/membarrier: fix missing local execution of ipi_sync_rq_state() efi: stub: omit SetVirtualAddressMap() if marked unsupported in RT_PROP table powerpc/64s: Fix instruction encoding for lis in ppc_function_entry() powerpc: Fix inverted SET_FULL_REGS bitop powerpc: Fix missing declaration of [en/dis]able_kernel_vsx() binfmt_misc: fix possible deadlock in bm_register_write x86/unwind/orc: Disable KASAN checking in the ORC unwinder, part 2 x86/sev-es: Introduce ip_within_syscall_gap() helper x86/sev-es: Check regs->sp is trusted before adjusting #VC IST stack x86/entry: Move nmi entry/exit into common code x86/sev-es: Correctly track IRQ states in runtime #VC handler x86/sev-es: Use __copy_from_user_inatomic() x86/entry: Fix entry/exit mismatch on failed fast 32-bit syscalls KVM: x86: Ensure deadline timer has truly expired before posting its IRQ KVM: kvmclock: Fix vCPUs > 64 can't be online/hotpluged KVM: arm64: Fix range alignment when walking page tables KVM: arm64: Avoid corrupting vCPU context register in guest exit KVM: arm64: nvhe: Save the SPE context early KVM: arm64: Reject VM creation when the default IPA size is unsupported KVM: arm64: Fix exclusive limit for IPA size mm/userfaultfd: fix memory corruption due to writeprotect mm/madvise: replace ptrace attach requirement for process_madvise KVM: arm64: Ensure I-cache isolation between vcpus of a same VM mm/page_alloc.c: refactor initialization of struct page for holes in memory layout xen/events: don't unmask an event channel when an eoi is pending xen/events: avoid handling the same event on two cpus at the same time KVM: arm64: Fix nVHE hyp panic host context restore RDMA/umem: Use ib_dma_max_seg_size instead of dma_get_max_seg_size Linux 5.10.24 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com> Change-Id: Ie53a3c1963066a18d41357b6be41cff00690bd40
This commit is contained in:
@@ -26,8 +26,9 @@ Date: September 2008
|
|||||||
Contact: Badari Pulavarty <pbadari@us.ibm.com>
|
Contact: Badari Pulavarty <pbadari@us.ibm.com>
|
||||||
Description:
|
Description:
|
||||||
The file /sys/devices/system/memory/memoryX/phys_device
|
The file /sys/devices/system/memory/memoryX/phys_device
|
||||||
is read-only and is designed to show the name of physical
|
is read-only; it is a legacy interface only ever used on s390x
|
||||||
memory device. Implementation is currently incomplete.
|
to expose the covered storage increment.
|
||||||
|
Users: Legacy s390-tools lsmem/chmem
|
||||||
|
|
||||||
What: /sys/devices/system/memory/memoryX/phys_index
|
What: /sys/devices/system/memory/memoryX/phys_index
|
||||||
Date: September 2008
|
Date: September 2008
|
||||||
|
@@ -160,8 +160,8 @@ Under each memory block, you can see 5 files:
|
|||||||
|
|
||||||
"online_movable", "online", "offline" command
|
"online_movable", "online", "offline" command
|
||||||
which will be performed on all sections in the block.
|
which will be performed on all sections in the block.
|
||||||
``phys_device`` read-only: designed to show the name of physical memory
|
``phys_device`` read-only: legacy interface only ever used on s390x to
|
||||||
device. This is not well implemented now.
|
expose the covered storage increment.
|
||||||
``removable`` read-only: contains an integer value indicating
|
``removable`` read-only: contains an integer value indicating
|
||||||
whether the memory block is removable or not
|
whether the memory block is removable or not
|
||||||
removable. A value of 1 indicates that the memory
|
removable. A value of 1 indicates that the memory
|
||||||
|
@@ -560,6 +560,27 @@ Some of these date from the very introduction of KMS in 2008 ...
|
|||||||
|
|
||||||
Level: Intermediate
|
Level: Intermediate
|
||||||
|
|
||||||
|
Remove automatic page mapping from dma-buf importing
|
||||||
|
----------------------------------------------------
|
||||||
|
|
||||||
|
When importing dma-bufs, the dma-buf and PRIME frameworks automatically map
|
||||||
|
imported pages into the importer's DMA area. drm_gem_prime_fd_to_handle() and
|
||||||
|
drm_gem_prime_handle_to_fd() require that importers call dma_buf_attach()
|
||||||
|
even if they never do actual device DMA, but only CPU access through
|
||||||
|
dma_buf_vmap(). This is a problem for USB devices, which do not support DMA
|
||||||
|
operations.
|
||||||
|
|
||||||
|
To fix the issue, automatic page mappings should be removed from the
|
||||||
|
buffer-sharing code. Fixing this is a bit more involved, since the import/export
|
||||||
|
cache is also tied to &drm_gem_object.import_attach. Meanwhile we paper over
|
||||||
|
this problem for USB devices by fishing out the USB host controller device, as
|
||||||
|
long as that supports DMA. Otherwise importing can still needlessly fail.
|
||||||
|
|
||||||
|
Contact: Thomas Zimmermann <tzimmermann@suse.de>, Daniel Vetter
|
||||||
|
|
||||||
|
Level: Advanced
|
||||||
|
|
||||||
|
|
||||||
Better Testing
|
Better Testing
|
||||||
==============
|
==============
|
||||||
|
|
||||||
|
@@ -144,77 +144,13 @@ Please send incremental versions on top of what has been merged in order to fix
|
|||||||
the patches the way they would look like if your latest patch series was to be
|
the patches the way they would look like if your latest patch series was to be
|
||||||
merged.
|
merged.
|
||||||
|
|
||||||
Q: How can I tell what patches are queued up for backporting to the various stable releases?
|
Q: Are there special rules regarding stable submissions on netdev?
|
||||||
--------------------------------------------------------------------------------------------
|
---------------------------------------------------------------
|
||||||
A: Normally Greg Kroah-Hartman collects stable commits himself, but for
|
While it used to be the case that netdev submissions were not supposed
|
||||||
networking, Dave collects up patches he deems critical for the
|
to carry explicit ``CC: stable@vger.kernel.org`` tags that is no longer
|
||||||
networking subsystem, and then hands them off to Greg.
|
the case today. Please follow the standard stable rules in
|
||||||
|
:ref:`Documentation/process/stable-kernel-rules.rst <stable_kernel_rules>`,
|
||||||
There is a patchworks queue that you can see here:
|
and make sure you include appropriate Fixes tags!
|
||||||
|
|
||||||
https://patchwork.kernel.org/bundle/netdev/stable/?state=*
|
|
||||||
|
|
||||||
It contains the patches which Dave has selected, but not yet handed off
|
|
||||||
to Greg. If Greg already has the patch, then it will be here:
|
|
||||||
|
|
||||||
https://git.kernel.org/pub/scm/linux/kernel/git/stable/stable-queue.git
|
|
||||||
|
|
||||||
A quick way to find whether the patch is in this stable-queue is to
|
|
||||||
simply clone the repo, and then git grep the mainline commit ID, e.g.
|
|
||||||
::
|
|
||||||
|
|
||||||
stable-queue$ git grep -l 284041ef21fdf2e
|
|
||||||
releases/3.0.84/ipv6-fix-possible-crashes-in-ip6_cork_release.patch
|
|
||||||
releases/3.4.51/ipv6-fix-possible-crashes-in-ip6_cork_release.patch
|
|
||||||
releases/3.9.8/ipv6-fix-possible-crashes-in-ip6_cork_release.patch
|
|
||||||
stable/stable-queue$
|
|
||||||
|
|
||||||
Q: I see a network patch and I think it should be backported to stable.
|
|
||||||
-----------------------------------------------------------------------
|
|
||||||
Q: Should I request it via stable@vger.kernel.org like the references in
|
|
||||||
the kernel's Documentation/process/stable-kernel-rules.rst file say?
|
|
||||||
A: No, not for networking. Check the stable queues as per above first
|
|
||||||
to see if it is already queued. If not, then send a mail to netdev,
|
|
||||||
listing the upstream commit ID and why you think it should be a stable
|
|
||||||
candidate.
|
|
||||||
|
|
||||||
Before you jump to go do the above, do note that the normal stable rules
|
|
||||||
in :ref:`Documentation/process/stable-kernel-rules.rst <stable_kernel_rules>`
|
|
||||||
still apply. So you need to explicitly indicate why it is a critical
|
|
||||||
fix and exactly what users are impacted. In addition, you need to
|
|
||||||
convince yourself that you *really* think it has been overlooked,
|
|
||||||
vs. having been considered and rejected.
|
|
||||||
|
|
||||||
Generally speaking, the longer it has had a chance to "soak" in
|
|
||||||
mainline, the better the odds that it is an OK candidate for stable. So
|
|
||||||
scrambling to request a commit be added the day after it appears should
|
|
||||||
be avoided.
|
|
||||||
|
|
||||||
Q: I have created a network patch and I think it should be backported to stable.
|
|
||||||
--------------------------------------------------------------------------------
|
|
||||||
Q: Should I add a Cc: stable@vger.kernel.org like the references in the
|
|
||||||
kernel's Documentation/ directory say?
|
|
||||||
A: No. See above answer. In short, if you think it really belongs in
|
|
||||||
stable, then ensure you write a decent commit log that describes who
|
|
||||||
gets impacted by the bug fix and how it manifests itself, and when the
|
|
||||||
bug was introduced. If you do that properly, then the commit will get
|
|
||||||
handled appropriately and most likely get put in the patchworks stable
|
|
||||||
queue if it really warrants it.
|
|
||||||
|
|
||||||
If you think there is some valid information relating to it being in
|
|
||||||
stable that does *not* belong in the commit log, then use the three dash
|
|
||||||
marker line as described in
|
|
||||||
:ref:`Documentation/process/submitting-patches.rst <the_canonical_patch_format>`
|
|
||||||
to temporarily embed that information into the patch that you send.
|
|
||||||
|
|
||||||
Q: Are all networking bug fixes backported to all stable releases?
|
|
||||||
------------------------------------------------------------------
|
|
||||||
A: Due to capacity, Dave could only take care of the backports for the
|
|
||||||
last two stable releases. For earlier stable releases, each stable
|
|
||||||
branch maintainer is supposed to take care of them. If you find any
|
|
||||||
patch is missing from an earlier stable branch, please notify
|
|
||||||
stable@vger.kernel.org with either a commit ID or a formal patch
|
|
||||||
backported, and CC Dave and other relevant networking developers.
|
|
||||||
|
|
||||||
Q: Is the comment style convention different for the networking content?
|
Q: Is the comment style convention different for the networking content?
|
||||||
------------------------------------------------------------------------
|
------------------------------------------------------------------------
|
||||||
|
@@ -35,12 +35,6 @@ Rules on what kind of patches are accepted, and which ones are not, into the
|
|||||||
Procedure for submitting patches to the -stable tree
|
Procedure for submitting patches to the -stable tree
|
||||||
----------------------------------------------------
|
----------------------------------------------------
|
||||||
|
|
||||||
- If the patch covers files in net/ or drivers/net please follow netdev stable
|
|
||||||
submission guidelines as described in
|
|
||||||
:ref:`Documentation/networking/netdev-FAQ.rst <netdev-FAQ>`
|
|
||||||
after first checking the stable networking queue at
|
|
||||||
https://patchwork.kernel.org/bundle/netdev/stable/?state=*
|
|
||||||
to ensure the requested patch is not already queued up.
|
|
||||||
- Security patches should not be handled (solely) by the -stable review
|
- Security patches should not be handled (solely) by the -stable review
|
||||||
process but should follow the procedures in
|
process but should follow the procedures in
|
||||||
:ref:`Documentation/admin-guide/security-bugs.rst <securitybugs>`.
|
:ref:`Documentation/admin-guide/security-bugs.rst <securitybugs>`.
|
||||||
|
@@ -250,11 +250,6 @@ should also read
|
|||||||
:ref:`Documentation/process/stable-kernel-rules.rst <stable_kernel_rules>`
|
:ref:`Documentation/process/stable-kernel-rules.rst <stable_kernel_rules>`
|
||||||
in addition to this file.
|
in addition to this file.
|
||||||
|
|
||||||
Note, however, that some subsystem maintainers want to come to their own
|
|
||||||
conclusions on which patches should go to the stable trees. The networking
|
|
||||||
maintainer, in particular, would rather not see individual developers
|
|
||||||
adding lines like the above to their patches.
|
|
||||||
|
|
||||||
If changes affect userland-kernel interfaces, please send the MAN-PAGES
|
If changes affect userland-kernel interfaces, please send the MAN-PAGES
|
||||||
maintainer (as listed in the MAINTAINERS file) a man-pages patch, or at
|
maintainer (as listed in the MAINTAINERS file) a man-pages patch, or at
|
||||||
least a notification of the change, so that some information makes its way
|
least a notification of the change, so that some information makes its way
|
||||||
|
@@ -182,6 +182,9 @@ is dependent on the CPU capability and the kernel configuration. The limit can
|
|||||||
be retrieved using KVM_CAP_ARM_VM_IPA_SIZE of the KVM_CHECK_EXTENSION
|
be retrieved using KVM_CAP_ARM_VM_IPA_SIZE of the KVM_CHECK_EXTENSION
|
||||||
ioctl() at run-time.
|
ioctl() at run-time.
|
||||||
|
|
||||||
|
Creation of the VM will fail if the requested IPA size (whether it is
|
||||||
|
implicit or explicit) is unsupported on the host.
|
||||||
|
|
||||||
Please note that configuring the IPA size does not affect the capability
|
Please note that configuring the IPA size does not affect the capability
|
||||||
exposed by the guest CPUs in ID_AA64MMFR0_EL1[PARange]. It only affects
|
exposed by the guest CPUs in ID_AA64MMFR0_EL1[PARange]. It only affects
|
||||||
size of the address translated by the stage2 level (guest physical to
|
size of the address translated by the stage2 level (guest physical to
|
||||||
|
14
Makefile
14
Makefile
@@ -1,7 +1,7 @@
|
|||||||
# SPDX-License-Identifier: GPL-2.0
|
# SPDX-License-Identifier: GPL-2.0
|
||||||
VERSION = 5
|
VERSION = 5
|
||||||
PATCHLEVEL = 10
|
PATCHLEVEL = 10
|
||||||
SUBLEVEL = 23
|
SUBLEVEL = 24
|
||||||
EXTRAVERSION =
|
EXTRAVERSION =
|
||||||
NAME = Dare mighty things
|
NAME = Dare mighty things
|
||||||
|
|
||||||
@@ -1332,9 +1332,15 @@ define filechk_utsrelease.h
|
|||||||
endef
|
endef
|
||||||
|
|
||||||
define filechk_version.h
|
define filechk_version.h
|
||||||
echo \#define LINUX_VERSION_CODE $(shell \
|
if [ $(SUBLEVEL) -gt 255 ]; then \
|
||||||
expr $(VERSION) \* 65536 + 0$(PATCHLEVEL) \* 256 + 0$(SUBLEVEL)); \
|
echo \#define LINUX_VERSION_CODE $(shell \
|
||||||
echo '#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))'
|
expr $(VERSION) \* 65536 + 0$(PATCHLEVEL) \* 256 + 255); \
|
||||||
|
else \
|
||||||
|
echo \#define LINUX_VERSION_CODE $(shell \
|
||||||
|
expr $(VERSION) \* 65536 + 0$(PATCHLEVEL) \* 256 + $(SUBLEVEL)); \
|
||||||
|
fi; \
|
||||||
|
echo '#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + \
|
||||||
|
((c) > 255 ? 255 : (c)))'
|
||||||
endef
|
endef
|
||||||
|
|
||||||
$(version_h): FORCE
|
$(version_h): FORCE
|
||||||
|
@@ -1440,8 +1440,7 @@ ENTRY(efi_enter_kernel)
|
|||||||
mov r4, r0 @ preserve image base
|
mov r4, r0 @ preserve image base
|
||||||
mov r8, r1 @ preserve DT pointer
|
mov r8, r1 @ preserve DT pointer
|
||||||
|
|
||||||
ARM( adrl r0, call_cache_fn )
|
adr_l r0, call_cache_fn
|
||||||
THUMB( adr r0, call_cache_fn )
|
|
||||||
adr r1, 0f @ clean the region of code we
|
adr r1, 0f @ clean the region of code we
|
||||||
bl cache_clean_flush @ may run with the MMU off
|
bl cache_clean_flush @ may run with the MMU off
|
||||||
|
|
||||||
|
@@ -494,4 +494,88 @@ THUMB( orr \reg , \reg , #PSR_T_BIT )
|
|||||||
#define _ASM_NOKPROBE(entry)
|
#define _ASM_NOKPROBE(entry)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
.macro __adldst_l, op, reg, sym, tmp, c
|
||||||
|
.if __LINUX_ARM_ARCH__ < 7
|
||||||
|
ldr\c \tmp, .La\@
|
||||||
|
.subsection 1
|
||||||
|
.align 2
|
||||||
|
.La\@: .long \sym - .Lpc\@
|
||||||
|
.previous
|
||||||
|
.else
|
||||||
|
.ifnb \c
|
||||||
|
THUMB( ittt \c )
|
||||||
|
.endif
|
||||||
|
movw\c \tmp, #:lower16:\sym - .Lpc\@
|
||||||
|
movt\c \tmp, #:upper16:\sym - .Lpc\@
|
||||||
|
.endif
|
||||||
|
|
||||||
|
#ifndef CONFIG_THUMB2_KERNEL
|
||||||
|
.set .Lpc\@, . + 8 // PC bias
|
||||||
|
.ifc \op, add
|
||||||
|
add\c \reg, \tmp, pc
|
||||||
|
.else
|
||||||
|
\op\c \reg, [pc, \tmp]
|
||||||
|
.endif
|
||||||
|
#else
|
||||||
|
.Lb\@: add\c \tmp, \tmp, pc
|
||||||
|
/*
|
||||||
|
* In Thumb-2 builds, the PC bias depends on whether we are currently
|
||||||
|
* emitting into a .arm or a .thumb section. The size of the add opcode
|
||||||
|
* above will be 2 bytes when emitting in Thumb mode and 4 bytes when
|
||||||
|
* emitting in ARM mode, so let's use this to account for the bias.
|
||||||
|
*/
|
||||||
|
.set .Lpc\@, . + (. - .Lb\@)
|
||||||
|
|
||||||
|
.ifnc \op, add
|
||||||
|
\op\c \reg, [\tmp]
|
||||||
|
.endif
|
||||||
|
#endif
|
||||||
|
.endm
|
||||||
|
|
||||||
|
/*
|
||||||
|
* mov_l - move a constant value or [relocated] address into a register
|
||||||
|
*/
|
||||||
|
.macro mov_l, dst:req, imm:req
|
||||||
|
.if __LINUX_ARM_ARCH__ < 7
|
||||||
|
ldr \dst, =\imm
|
||||||
|
.else
|
||||||
|
movw \dst, #:lower16:\imm
|
||||||
|
movt \dst, #:upper16:\imm
|
||||||
|
.endif
|
||||||
|
.endm
|
||||||
|
|
||||||
|
/*
|
||||||
|
* adr_l - adr pseudo-op with unlimited range
|
||||||
|
*
|
||||||
|
* @dst: destination register
|
||||||
|
* @sym: name of the symbol
|
||||||
|
* @cond: conditional opcode suffix
|
||||||
|
*/
|
||||||
|
.macro adr_l, dst:req, sym:req, cond
|
||||||
|
__adldst_l add, \dst, \sym, \dst, \cond
|
||||||
|
.endm
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ldr_l - ldr <literal> pseudo-op with unlimited range
|
||||||
|
*
|
||||||
|
* @dst: destination register
|
||||||
|
* @sym: name of the symbol
|
||||||
|
* @cond: conditional opcode suffix
|
||||||
|
*/
|
||||||
|
.macro ldr_l, dst:req, sym:req, cond
|
||||||
|
__adldst_l ldr, \dst, \sym, \dst, \cond
|
||||||
|
.endm
|
||||||
|
|
||||||
|
/*
|
||||||
|
* str_l - str <literal> pseudo-op with unlimited range
|
||||||
|
*
|
||||||
|
* @src: source register
|
||||||
|
* @sym: name of the symbol
|
||||||
|
* @tmp: mandatory scratch register
|
||||||
|
* @cond: conditional opcode suffix
|
||||||
|
*/
|
||||||
|
.macro str_l, src:req, sym:req, tmp:req, cond
|
||||||
|
__adldst_l str, \src, \sym, \tmp, \cond
|
||||||
|
.endm
|
||||||
|
|
||||||
#endif /* __ASM_ASSEMBLER_H__ */
|
#endif /* __ASM_ASSEMBLER_H__ */
|
||||||
|
@@ -16,6 +16,7 @@
|
|||||||
#include <asm/thread_info.h>
|
#include <asm/thread_info.h>
|
||||||
#include <asm/asm-offsets.h>
|
#include <asm/asm-offsets.h>
|
||||||
#include <asm/assembler.h>
|
#include <asm/assembler.h>
|
||||||
|
#include "iwmmxt.h"
|
||||||
|
|
||||||
#if defined(CONFIG_CPU_PJ4) || defined(CONFIG_CPU_PJ4B)
|
#if defined(CONFIG_CPU_PJ4) || defined(CONFIG_CPU_PJ4B)
|
||||||
#define PJ4(code...) code
|
#define PJ4(code...) code
|
||||||
@@ -113,33 +114,33 @@ concan_save:
|
|||||||
|
|
||||||
concan_dump:
|
concan_dump:
|
||||||
|
|
||||||
wstrw wCSSF, [r1, #MMX_WCSSF]
|
wstrw wCSSF, r1, MMX_WCSSF
|
||||||
wstrw wCASF, [r1, #MMX_WCASF]
|
wstrw wCASF, r1, MMX_WCASF
|
||||||
wstrw wCGR0, [r1, #MMX_WCGR0]
|
wstrw wCGR0, r1, MMX_WCGR0
|
||||||
wstrw wCGR1, [r1, #MMX_WCGR1]
|
wstrw wCGR1, r1, MMX_WCGR1
|
||||||
wstrw wCGR2, [r1, #MMX_WCGR2]
|
wstrw wCGR2, r1, MMX_WCGR2
|
||||||
wstrw wCGR3, [r1, #MMX_WCGR3]
|
wstrw wCGR3, r1, MMX_WCGR3
|
||||||
|
|
||||||
1: @ MUP? wRn
|
1: @ MUP? wRn
|
||||||
tst r2, #0x2
|
tst r2, #0x2
|
||||||
beq 2f
|
beq 2f
|
||||||
|
|
||||||
wstrd wR0, [r1, #MMX_WR0]
|
wstrd wR0, r1, MMX_WR0
|
||||||
wstrd wR1, [r1, #MMX_WR1]
|
wstrd wR1, r1, MMX_WR1
|
||||||
wstrd wR2, [r1, #MMX_WR2]
|
wstrd wR2, r1, MMX_WR2
|
||||||
wstrd wR3, [r1, #MMX_WR3]
|
wstrd wR3, r1, MMX_WR3
|
||||||
wstrd wR4, [r1, #MMX_WR4]
|
wstrd wR4, r1, MMX_WR4
|
||||||
wstrd wR5, [r1, #MMX_WR5]
|
wstrd wR5, r1, MMX_WR5
|
||||||
wstrd wR6, [r1, #MMX_WR6]
|
wstrd wR6, r1, MMX_WR6
|
||||||
wstrd wR7, [r1, #MMX_WR7]
|
wstrd wR7, r1, MMX_WR7
|
||||||
wstrd wR8, [r1, #MMX_WR8]
|
wstrd wR8, r1, MMX_WR8
|
||||||
wstrd wR9, [r1, #MMX_WR9]
|
wstrd wR9, r1, MMX_WR9
|
||||||
wstrd wR10, [r1, #MMX_WR10]
|
wstrd wR10, r1, MMX_WR10
|
||||||
wstrd wR11, [r1, #MMX_WR11]
|
wstrd wR11, r1, MMX_WR11
|
||||||
wstrd wR12, [r1, #MMX_WR12]
|
wstrd wR12, r1, MMX_WR12
|
||||||
wstrd wR13, [r1, #MMX_WR13]
|
wstrd wR13, r1, MMX_WR13
|
||||||
wstrd wR14, [r1, #MMX_WR14]
|
wstrd wR14, r1, MMX_WR14
|
||||||
wstrd wR15, [r1, #MMX_WR15]
|
wstrd wR15, r1, MMX_WR15
|
||||||
|
|
||||||
2: teq r0, #0 @ anything to load?
|
2: teq r0, #0 @ anything to load?
|
||||||
reteq lr @ if not, return
|
reteq lr @ if not, return
|
||||||
@@ -147,30 +148,30 @@ concan_dump:
|
|||||||
concan_load:
|
concan_load:
|
||||||
|
|
||||||
@ Load wRn
|
@ Load wRn
|
||||||
wldrd wR0, [r0, #MMX_WR0]
|
wldrd wR0, r0, MMX_WR0
|
||||||
wldrd wR1, [r0, #MMX_WR1]
|
wldrd wR1, r0, MMX_WR1
|
||||||
wldrd wR2, [r0, #MMX_WR2]
|
wldrd wR2, r0, MMX_WR2
|
||||||
wldrd wR3, [r0, #MMX_WR3]
|
wldrd wR3, r0, MMX_WR3
|
||||||
wldrd wR4, [r0, #MMX_WR4]
|
wldrd wR4, r0, MMX_WR4
|
||||||
wldrd wR5, [r0, #MMX_WR5]
|
wldrd wR5, r0, MMX_WR5
|
||||||
wldrd wR6, [r0, #MMX_WR6]
|
wldrd wR6, r0, MMX_WR6
|
||||||
wldrd wR7, [r0, #MMX_WR7]
|
wldrd wR7, r0, MMX_WR7
|
||||||
wldrd wR8, [r0, #MMX_WR8]
|
wldrd wR8, r0, MMX_WR8
|
||||||
wldrd wR9, [r0, #MMX_WR9]
|
wldrd wR9, r0, MMX_WR9
|
||||||
wldrd wR10, [r0, #MMX_WR10]
|
wldrd wR10, r0, MMX_WR10
|
||||||
wldrd wR11, [r0, #MMX_WR11]
|
wldrd wR11, r0, MMX_WR11
|
||||||
wldrd wR12, [r0, #MMX_WR12]
|
wldrd wR12, r0, MMX_WR12
|
||||||
wldrd wR13, [r0, #MMX_WR13]
|
wldrd wR13, r0, MMX_WR13
|
||||||
wldrd wR14, [r0, #MMX_WR14]
|
wldrd wR14, r0, MMX_WR14
|
||||||
wldrd wR15, [r0, #MMX_WR15]
|
wldrd wR15, r0, MMX_WR15
|
||||||
|
|
||||||
@ Load wCx
|
@ Load wCx
|
||||||
wldrw wCSSF, [r0, #MMX_WCSSF]
|
wldrw wCSSF, r0, MMX_WCSSF
|
||||||
wldrw wCASF, [r0, #MMX_WCASF]
|
wldrw wCASF, r0, MMX_WCASF
|
||||||
wldrw wCGR0, [r0, #MMX_WCGR0]
|
wldrw wCGR0, r0, MMX_WCGR0
|
||||||
wldrw wCGR1, [r0, #MMX_WCGR1]
|
wldrw wCGR1, r0, MMX_WCGR1
|
||||||
wldrw wCGR2, [r0, #MMX_WCGR2]
|
wldrw wCGR2, r0, MMX_WCGR2
|
||||||
wldrw wCGR3, [r0, #MMX_WCGR3]
|
wldrw wCGR3, r0, MMX_WCGR3
|
||||||
|
|
||||||
@ clear CUP/MUP (only if r1 != 0)
|
@ clear CUP/MUP (only if r1 != 0)
|
||||||
teq r1, #0
|
teq r1, #0
|
||||||
|
47
arch/arm/kernel/iwmmxt.h
Normal file
47
arch/arm/kernel/iwmmxt.h
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
/* SPDX-License-Identifier: GPL-2.0 */
|
||||||
|
|
||||||
|
#ifndef __IWMMXT_H__
|
||||||
|
#define __IWMMXT_H__
|
||||||
|
|
||||||
|
.irp b, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
|
||||||
|
.set .LwR\b, \b
|
||||||
|
.set .Lr\b, \b
|
||||||
|
.endr
|
||||||
|
|
||||||
|
.set .LwCSSF, 0x2
|
||||||
|
.set .LwCASF, 0x3
|
||||||
|
.set .LwCGR0, 0x8
|
||||||
|
.set .LwCGR1, 0x9
|
||||||
|
.set .LwCGR2, 0xa
|
||||||
|
.set .LwCGR3, 0xb
|
||||||
|
|
||||||
|
.macro wldrd, reg:req, base:req, offset:req
|
||||||
|
.inst 0xedd00100 | (.L\reg << 12) | (.L\base << 16) | (\offset >> 2)
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro wldrw, reg:req, base:req, offset:req
|
||||||
|
.inst 0xfd900100 | (.L\reg << 12) | (.L\base << 16) | (\offset >> 2)
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro wstrd, reg:req, base:req, offset:req
|
||||||
|
.inst 0xedc00100 | (.L\reg << 12) | (.L\base << 16) | (\offset >> 2)
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro wstrw, reg:req, base:req, offset:req
|
||||||
|
.inst 0xfd800100 | (.L\reg << 12) | (.L\base << 16) | (\offset >> 2)
|
||||||
|
.endm
|
||||||
|
|
||||||
|
#ifdef __clang__
|
||||||
|
|
||||||
|
#define wCon c1
|
||||||
|
|
||||||
|
.macro tmrc, dest:req, control:req
|
||||||
|
mrc p1, 0, \dest, \control, c0, 0
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro tmcr, control:req, src:req
|
||||||
|
mcr p1, 0, \src, \control, c0, 0
|
||||||
|
.endm
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
@@ -335,6 +335,11 @@ static inline void *phys_to_virt(phys_addr_t x)
|
|||||||
#define ARCH_PFN_OFFSET ((unsigned long)PHYS_PFN_OFFSET)
|
#define ARCH_PFN_OFFSET ((unsigned long)PHYS_PFN_OFFSET)
|
||||||
|
|
||||||
#if !defined(CONFIG_SPARSEMEM_VMEMMAP) || defined(CONFIG_DEBUG_VIRTUAL)
|
#if !defined(CONFIG_SPARSEMEM_VMEMMAP) || defined(CONFIG_DEBUG_VIRTUAL)
|
||||||
|
#define page_to_virt(x) ({ \
|
||||||
|
__typeof__(x) __page = x; \
|
||||||
|
void *__addr = __va(page_to_phys(__page)); \
|
||||||
|
(void *)__tag_set((const void *)__addr, page_kasan_tag(__page));\
|
||||||
|
})
|
||||||
#define virt_to_page(x) pfn_to_page(virt_to_pfn(x))
|
#define virt_to_page(x) pfn_to_page(virt_to_pfn(x))
|
||||||
#else
|
#else
|
||||||
#define page_to_virt(x) ({ \
|
#define page_to_virt(x) ({ \
|
||||||
|
@@ -65,10 +65,7 @@ extern u64 idmap_ptrs_per_pgd;
|
|||||||
|
|
||||||
static inline bool __cpu_uses_extended_idmap(void)
|
static inline bool __cpu_uses_extended_idmap(void)
|
||||||
{
|
{
|
||||||
if (IS_ENABLED(CONFIG_ARM64_VA_BITS_52))
|
return unlikely(idmap_t0sz != TCR_T0SZ(vabits_actual));
|
||||||
return false;
|
|
||||||
|
|
||||||
return unlikely(idmap_t0sz != TCR_T0SZ(VA_BITS));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@@ -334,7 +334,7 @@ SYM_FUNC_START_LOCAL(__create_page_tables)
|
|||||||
*/
|
*/
|
||||||
adrp x5, __idmap_text_end
|
adrp x5, __idmap_text_end
|
||||||
clz x5, x5
|
clz x5, x5
|
||||||
cmp x5, TCR_T0SZ(VA_BITS) // default T0SZ small enough?
|
cmp x5, TCR_T0SZ(VA_BITS_MIN) // default T0SZ small enough?
|
||||||
b.ge 1f // .. then skip VA range extension
|
b.ge 1f // .. then skip VA range extension
|
||||||
|
|
||||||
adr_l x6, idmap_t0sz
|
adr_l x6, idmap_t0sz
|
||||||
|
@@ -460,7 +460,7 @@ static inline int armv8pmu_counter_has_overflowed(u32 pmnc, int idx)
|
|||||||
return pmnc & BIT(ARMV8_IDX_TO_COUNTER(idx));
|
return pmnc & BIT(ARMV8_IDX_TO_COUNTER(idx));
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline u32 armv8pmu_read_evcntr(int idx)
|
static inline u64 armv8pmu_read_evcntr(int idx)
|
||||||
{
|
{
|
||||||
u32 counter = ARMV8_IDX_TO_COUNTER(idx);
|
u32 counter = ARMV8_IDX_TO_COUNTER(idx);
|
||||||
|
|
||||||
|
@@ -152,7 +152,7 @@ SYM_FUNC_END(__hyp_do_panic)
|
|||||||
|
|
||||||
.macro invalid_host_el1_vect
|
.macro invalid_host_el1_vect
|
||||||
.align 7
|
.align 7
|
||||||
mov x0, xzr /* restore_host = false */
|
mov x0, xzr /* host_ctxt = NULL */
|
||||||
mrs x1, spsr_el2
|
mrs x1, spsr_el2
|
||||||
mrs x2, elr_el2
|
mrs x2, elr_el2
|
||||||
mrs x3, par_el1
|
mrs x3, par_el1
|
||||||
|
@@ -1312,8 +1312,7 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm,
|
|||||||
* Prevent userspace from creating a memory region outside of the IPA
|
* Prevent userspace from creating a memory region outside of the IPA
|
||||||
* space addressable by the KVM guest IPA space.
|
* space addressable by the KVM guest IPA space.
|
||||||
*/
|
*/
|
||||||
if (memslot->base_gfn + memslot->npages >=
|
if ((memslot->base_gfn + memslot->npages) > (kvm_phys_size(kvm) >> PAGE_SHIFT))
|
||||||
(kvm_phys_size(kvm) >> PAGE_SHIFT))
|
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
mmap_read_lock(current->mm);
|
mmap_read_lock(current->mm);
|
||||||
|
@@ -324,10 +324,9 @@ int kvm_set_ipa_limit(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
kvm_ipa_limit = id_aa64mmfr0_parange_to_phys_shift(parange);
|
kvm_ipa_limit = id_aa64mmfr0_parange_to_phys_shift(parange);
|
||||||
WARN(kvm_ipa_limit < KVM_PHYS_SHIFT,
|
kvm_info("IPA Size Limit: %d bits%s\n", kvm_ipa_limit,
|
||||||
"KVM IPA Size Limit (%d bits) is smaller than default size\n",
|
((kvm_ipa_limit < KVM_PHYS_SHIFT) ?
|
||||||
kvm_ipa_limit);
|
" (Reduced IPA size, limited VM/VMM compatibility)" : ""));
|
||||||
kvm_info("IPA Size Limit: %d bits\n", kvm_ipa_limit);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -356,6 +355,11 @@ int kvm_arm_setup_stage2(struct kvm *kvm, unsigned long type)
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
} else {
|
} else {
|
||||||
phys_shift = KVM_PHYS_SHIFT;
|
phys_shift = KVM_PHYS_SHIFT;
|
||||||
|
if (phys_shift > kvm_ipa_limit) {
|
||||||
|
pr_warn_once("%s using unsupported default IPA limit, upgrade your VMM\n",
|
||||||
|
current->comm);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mmfr0 = read_sanitised_ftr_reg(SYS_ID_AA64MMFR0_EL1);
|
mmfr0 = read_sanitised_ftr_reg(SYS_ID_AA64MMFR0_EL1);
|
||||||
|
@@ -218,6 +218,18 @@ int pfn_valid(unsigned long pfn)
|
|||||||
|
|
||||||
if (!valid_section(__pfn_to_section(pfn)))
|
if (!valid_section(__pfn_to_section(pfn)))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ZONE_DEVICE memory does not have the memblock entries.
|
||||||
|
* memblock_is_map_memory() check for ZONE_DEVICE based
|
||||||
|
* addresses will always fail. Even the normal hotplugged
|
||||||
|
* memory will never have MEMBLOCK_NOMAP flag set in their
|
||||||
|
* memblock entries. Skip memblock search for all non early
|
||||||
|
* memory sections covering all of hotplug memory including
|
||||||
|
* both normal and ZONE_DEVICE based.
|
||||||
|
*/
|
||||||
|
if (!early_section(__pfn_to_section(pfn)))
|
||||||
|
return pfn_section_valid(__pfn_to_section(pfn), pfn);
|
||||||
#endif
|
#endif
|
||||||
return memblock_is_map_memory(addr);
|
return memblock_is_map_memory(addr);
|
||||||
}
|
}
|
||||||
|
@@ -40,7 +40,7 @@
|
|||||||
#define NO_BLOCK_MAPPINGS BIT(0)
|
#define NO_BLOCK_MAPPINGS BIT(0)
|
||||||
#define NO_CONT_MAPPINGS BIT(1)
|
#define NO_CONT_MAPPINGS BIT(1)
|
||||||
|
|
||||||
u64 idmap_t0sz = TCR_T0SZ(VA_BITS);
|
u64 idmap_t0sz = TCR_T0SZ(VA_BITS_MIN);
|
||||||
u64 idmap_ptrs_per_pgd = PTRS_PER_PGD;
|
u64 idmap_ptrs_per_pgd = PTRS_PER_PGD;
|
||||||
|
|
||||||
u64 __section(".mmuoff.data.write") vabits_actual;
|
u64 __section(".mmuoff.data.write") vabits_actual;
|
||||||
|
@@ -12,8 +12,8 @@ AFLAGS_chacha-core.o += -O2 # needed to fill branch delay slots
|
|||||||
obj-$(CONFIG_CRYPTO_POLY1305_MIPS) += poly1305-mips.o
|
obj-$(CONFIG_CRYPTO_POLY1305_MIPS) += poly1305-mips.o
|
||||||
poly1305-mips-y := poly1305-core.o poly1305-glue.o
|
poly1305-mips-y := poly1305-core.o poly1305-glue.o
|
||||||
|
|
||||||
perlasm-flavour-$(CONFIG_CPU_MIPS32) := o32
|
perlasm-flavour-$(CONFIG_32BIT) := o32
|
||||||
perlasm-flavour-$(CONFIG_CPU_MIPS64) := 64
|
perlasm-flavour-$(CONFIG_64BIT) := 64
|
||||||
|
|
||||||
quiet_cmd_perlasm = PERLASM $@
|
quiet_cmd_perlasm = PERLASM $@
|
||||||
cmd_perlasm = $(PERL) $(<) $(perlasm-flavour-y) $(@)
|
cmd_perlasm = $(PERL) $(<) $(perlasm-flavour-y) $(@)
|
||||||
|
@@ -73,7 +73,7 @@ void __patch_exception(int exc, unsigned long addr);
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define OP_RT_RA_MASK 0xffff0000UL
|
#define OP_RT_RA_MASK 0xffff0000UL
|
||||||
#define LIS_R2 0x3c020000UL
|
#define LIS_R2 0x3c400000UL
|
||||||
#define ADDIS_R2_R12 0x3c4c0000UL
|
#define ADDIS_R2_R12 0x3c4c0000UL
|
||||||
#define ADDI_R2_R2 0x38420000UL
|
#define ADDI_R2_R2 0x38420000UL
|
||||||
|
|
||||||
|
@@ -59,6 +59,9 @@ struct machdep_calls {
|
|||||||
int (*pcibios_root_bridge_prepare)(struct pci_host_bridge
|
int (*pcibios_root_bridge_prepare)(struct pci_host_bridge
|
||||||
*bridge);
|
*bridge);
|
||||||
|
|
||||||
|
/* finds all the pci_controllers present at boot */
|
||||||
|
void (*discover_phbs)(void);
|
||||||
|
|
||||||
/* To setup PHBs when using automatic OF platform driver for PCI */
|
/* To setup PHBs when using automatic OF platform driver for PCI */
|
||||||
int (*pci_setup_phb)(struct pci_controller *host);
|
int (*pci_setup_phb)(struct pci_controller *host);
|
||||||
|
|
||||||
|
@@ -62,6 +62,9 @@ struct pt_regs
|
|||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#define STACK_FRAME_WITH_PT_REGS (STACK_FRAME_OVERHEAD + sizeof(struct pt_regs))
|
||||||
|
|
||||||
#ifdef __powerpc64__
|
#ifdef __powerpc64__
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -190,7 +193,7 @@ extern int ptrace_put_reg(struct task_struct *task, int regno,
|
|||||||
#define TRAP_FLAGS_MASK 0x11
|
#define TRAP_FLAGS_MASK 0x11
|
||||||
#define TRAP(regs) ((regs)->trap & ~TRAP_FLAGS_MASK)
|
#define TRAP(regs) ((regs)->trap & ~TRAP_FLAGS_MASK)
|
||||||
#define FULL_REGS(regs) (((regs)->trap & 1) == 0)
|
#define FULL_REGS(regs) (((regs)->trap & 1) == 0)
|
||||||
#define SET_FULL_REGS(regs) ((regs)->trap |= 1)
|
#define SET_FULL_REGS(regs) ((regs)->trap &= ~1)
|
||||||
#endif
|
#endif
|
||||||
#define CHECK_FULL_REGS(regs) BUG_ON(!FULL_REGS(regs))
|
#define CHECK_FULL_REGS(regs) BUG_ON(!FULL_REGS(regs))
|
||||||
#define NV_REG_POISON 0xdeadbeefdeadbeefUL
|
#define NV_REG_POISON 0xdeadbeefdeadbeefUL
|
||||||
@@ -205,7 +208,7 @@ extern int ptrace_put_reg(struct task_struct *task, int regno,
|
|||||||
#define TRAP_FLAGS_MASK 0x1F
|
#define TRAP_FLAGS_MASK 0x1F
|
||||||
#define TRAP(regs) ((regs)->trap & ~TRAP_FLAGS_MASK)
|
#define TRAP(regs) ((regs)->trap & ~TRAP_FLAGS_MASK)
|
||||||
#define FULL_REGS(regs) (((regs)->trap & 1) == 0)
|
#define FULL_REGS(regs) (((regs)->trap & 1) == 0)
|
||||||
#define SET_FULL_REGS(regs) ((regs)->trap |= 1)
|
#define SET_FULL_REGS(regs) ((regs)->trap &= ~1)
|
||||||
#define IS_CRITICAL_EXC(regs) (((regs)->trap & 2) != 0)
|
#define IS_CRITICAL_EXC(regs) (((regs)->trap & 2) != 0)
|
||||||
#define IS_MCHECK_EXC(regs) (((regs)->trap & 4) != 0)
|
#define IS_MCHECK_EXC(regs) (((regs)->trap & 4) != 0)
|
||||||
#define IS_DEBUG_EXC(regs) (((regs)->trap & 8) != 0)
|
#define IS_DEBUG_EXC(regs) (((regs)->trap & 8) != 0)
|
||||||
|
@@ -71,6 +71,16 @@ static inline void disable_kernel_vsx(void)
|
|||||||
{
|
{
|
||||||
msr_check_and_clear(MSR_FP|MSR_VEC|MSR_VSX);
|
msr_check_and_clear(MSR_FP|MSR_VEC|MSR_VSX);
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
static inline void enable_kernel_vsx(void)
|
||||||
|
{
|
||||||
|
BUILD_BUG();
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void disable_kernel_vsx(void)
|
||||||
|
{
|
||||||
|
BUILD_BUG();
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_SPE
|
#ifdef CONFIG_SPE
|
||||||
|
@@ -307,7 +307,7 @@ int main(void)
|
|||||||
|
|
||||||
/* Interrupt register frame */
|
/* Interrupt register frame */
|
||||||
DEFINE(INT_FRAME_SIZE, STACK_INT_FRAME_SIZE);
|
DEFINE(INT_FRAME_SIZE, STACK_INT_FRAME_SIZE);
|
||||||
DEFINE(SWITCH_FRAME_SIZE, STACK_FRAME_OVERHEAD + sizeof(struct pt_regs));
|
DEFINE(SWITCH_FRAME_SIZE, STACK_FRAME_WITH_PT_REGS);
|
||||||
STACK_PT_REGS_OFFSET(GPR0, gpr[0]);
|
STACK_PT_REGS_OFFSET(GPR0, gpr[0]);
|
||||||
STACK_PT_REGS_OFFSET(GPR1, gpr[1]);
|
STACK_PT_REGS_OFFSET(GPR1, gpr[1]);
|
||||||
STACK_PT_REGS_OFFSET(GPR2, gpr[2]);
|
STACK_PT_REGS_OFFSET(GPR2, gpr[2]);
|
||||||
|
@@ -470,7 +470,7 @@ DEFINE_FIXED_SYMBOL(\name\()_common_real)
|
|||||||
|
|
||||||
ld r10,PACAKMSR(r13) /* get MSR value for kernel */
|
ld r10,PACAKMSR(r13) /* get MSR value for kernel */
|
||||||
/* MSR[RI] is clear iff using SRR regs */
|
/* MSR[RI] is clear iff using SRR regs */
|
||||||
.if IHSRR == EXC_HV_OR_STD
|
.if IHSRR_IF_HVMODE
|
||||||
BEGIN_FTR_SECTION
|
BEGIN_FTR_SECTION
|
||||||
xori r10,r10,MSR_RI
|
xori r10,r10,MSR_RI
|
||||||
END_FTR_SECTION_IFCLR(CPU_FTR_HVMODE)
|
END_FTR_SECTION_IFCLR(CPU_FTR_HVMODE)
|
||||||
|
@@ -461,10 +461,11 @@ InstructionTLBMiss:
|
|||||||
cmplw 0,r1,r3
|
cmplw 0,r1,r3
|
||||||
#endif
|
#endif
|
||||||
mfspr r2, SPRN_SPRG_PGDIR
|
mfspr r2, SPRN_SPRG_PGDIR
|
||||||
li r1,_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_EXEC
|
li r1,_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_EXEC | _PAGE_USER
|
||||||
#if defined(CONFIG_MODULES) || defined(CONFIG_DEBUG_PAGEALLOC)
|
#if defined(CONFIG_MODULES) || defined(CONFIG_DEBUG_PAGEALLOC)
|
||||||
bgt- 112f
|
bgt- 112f
|
||||||
lis r2, (swapper_pg_dir - PAGE_OFFSET)@ha /* if kernel address, use */
|
lis r2, (swapper_pg_dir - PAGE_OFFSET)@ha /* if kernel address, use */
|
||||||
|
li r1,_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_EXEC
|
||||||
addi r2, r2, (swapper_pg_dir - PAGE_OFFSET)@l /* kernel page table */
|
addi r2, r2, (swapper_pg_dir - PAGE_OFFSET)@l /* kernel page table */
|
||||||
#endif
|
#endif
|
||||||
112: rlwimi r2,r3,12,20,29 /* insert top 10 bits of address */
|
112: rlwimi r2,r3,12,20,29 /* insert top 10 bits of address */
|
||||||
@@ -523,9 +524,10 @@ DataLoadTLBMiss:
|
|||||||
lis r1, TASK_SIZE@h /* check if kernel address */
|
lis r1, TASK_SIZE@h /* check if kernel address */
|
||||||
cmplw 0,r1,r3
|
cmplw 0,r1,r3
|
||||||
mfspr r2, SPRN_SPRG_PGDIR
|
mfspr r2, SPRN_SPRG_PGDIR
|
||||||
li r1, _PAGE_PRESENT | _PAGE_ACCESSED
|
li r1, _PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_USER
|
||||||
bgt- 112f
|
bgt- 112f
|
||||||
lis r2, (swapper_pg_dir - PAGE_OFFSET)@ha /* if kernel address, use */
|
lis r2, (swapper_pg_dir - PAGE_OFFSET)@ha /* if kernel address, use */
|
||||||
|
li r1, _PAGE_PRESENT | _PAGE_ACCESSED
|
||||||
addi r2, r2, (swapper_pg_dir - PAGE_OFFSET)@l /* kernel page table */
|
addi r2, r2, (swapper_pg_dir - PAGE_OFFSET)@l /* kernel page table */
|
||||||
112: rlwimi r2,r3,12,20,29 /* insert top 10 bits of address */
|
112: rlwimi r2,r3,12,20,29 /* insert top 10 bits of address */
|
||||||
lwz r2,0(r2) /* get pmd entry */
|
lwz r2,0(r2) /* get pmd entry */
|
||||||
@@ -599,9 +601,10 @@ DataStoreTLBMiss:
|
|||||||
lis r1, TASK_SIZE@h /* check if kernel address */
|
lis r1, TASK_SIZE@h /* check if kernel address */
|
||||||
cmplw 0,r1,r3
|
cmplw 0,r1,r3
|
||||||
mfspr r2, SPRN_SPRG_PGDIR
|
mfspr r2, SPRN_SPRG_PGDIR
|
||||||
li r1, _PAGE_RW | _PAGE_DIRTY | _PAGE_PRESENT | _PAGE_ACCESSED
|
li r1, _PAGE_RW | _PAGE_DIRTY | _PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_USER
|
||||||
bgt- 112f
|
bgt- 112f
|
||||||
lis r2, (swapper_pg_dir - PAGE_OFFSET)@ha /* if kernel address, use */
|
lis r2, (swapper_pg_dir - PAGE_OFFSET)@ha /* if kernel address, use */
|
||||||
|
li r1, _PAGE_RW | _PAGE_DIRTY | _PAGE_PRESENT | _PAGE_ACCESSED
|
||||||
addi r2, r2, (swapper_pg_dir - PAGE_OFFSET)@l /* kernel page table */
|
addi r2, r2, (swapper_pg_dir - PAGE_OFFSET)@l /* kernel page table */
|
||||||
112: rlwimi r2,r3,12,20,29 /* insert top 10 bits of address */
|
112: rlwimi r2,r3,12,20,29 /* insert top 10 bits of address */
|
||||||
lwz r2,0(r2) /* get pmd entry */
|
lwz r2,0(r2) /* get pmd entry */
|
||||||
|
@@ -1625,3 +1625,13 @@ static void fixup_hide_host_resource_fsl(struct pci_dev *dev)
|
|||||||
}
|
}
|
||||||
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MOTOROLA, PCI_ANY_ID, fixup_hide_host_resource_fsl);
|
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MOTOROLA, PCI_ANY_ID, fixup_hide_host_resource_fsl);
|
||||||
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_FREESCALE, PCI_ANY_ID, fixup_hide_host_resource_fsl);
|
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_FREESCALE, PCI_ANY_ID, fixup_hide_host_resource_fsl);
|
||||||
|
|
||||||
|
|
||||||
|
static int __init discover_phbs(void)
|
||||||
|
{
|
||||||
|
if (ppc_md.discover_phbs)
|
||||||
|
ppc_md.discover_phbs();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
core_initcall(discover_phbs);
|
||||||
|
@@ -2170,7 +2170,7 @@ void show_stack(struct task_struct *tsk, unsigned long *stack,
|
|||||||
* See if this is an exception frame.
|
* See if this is an exception frame.
|
||||||
* We look for the "regshere" marker in the current frame.
|
* We look for the "regshere" marker in the current frame.
|
||||||
*/
|
*/
|
||||||
if (validate_sp(sp, tsk, STACK_INT_FRAME_SIZE)
|
if (validate_sp(sp, tsk, STACK_FRAME_WITH_PT_REGS)
|
||||||
&& stack[STACK_FRAME_MARKER] == STACK_FRAME_REGS_MARKER) {
|
&& stack[STACK_FRAME_MARKER] == STACK_FRAME_REGS_MARKER) {
|
||||||
struct pt_regs *regs = (struct pt_regs *)
|
struct pt_regs *regs = (struct pt_regs *)
|
||||||
(sp + STACK_FRAME_OVERHEAD);
|
(sp + STACK_FRAME_OVERHEAD);
|
||||||
|
@@ -509,8 +509,11 @@ out:
|
|||||||
die("Unrecoverable nested System Reset", regs, SIGABRT);
|
die("Unrecoverable nested System Reset", regs, SIGABRT);
|
||||||
#endif
|
#endif
|
||||||
/* Must die if the interrupt is not recoverable */
|
/* Must die if the interrupt is not recoverable */
|
||||||
if (!(regs->msr & MSR_RI))
|
if (!(regs->msr & MSR_RI)) {
|
||||||
|
/* For the reason explained in die_mce, nmi_exit before die */
|
||||||
|
nmi_exit();
|
||||||
die("Unrecoverable System Reset", regs, SIGABRT);
|
die("Unrecoverable System Reset", regs, SIGABRT);
|
||||||
|
}
|
||||||
|
|
||||||
if (saved_hsrrs) {
|
if (saved_hsrrs) {
|
||||||
mtspr(SPRN_HSRR0, hsrr0);
|
mtspr(SPRN_HSRR0, hsrr0);
|
||||||
|
@@ -211,7 +211,7 @@ static inline void perf_get_data_addr(struct perf_event *event, struct pt_regs *
|
|||||||
if (!(mmcra & MMCRA_SAMPLE_ENABLE) || sdar_valid)
|
if (!(mmcra & MMCRA_SAMPLE_ENABLE) || sdar_valid)
|
||||||
*addrp = mfspr(SPRN_SDAR);
|
*addrp = mfspr(SPRN_SDAR);
|
||||||
|
|
||||||
if (is_kernel_addr(mfspr(SPRN_SDAR)) && perf_allow_kernel(&event->attr) != 0)
|
if (is_kernel_addr(mfspr(SPRN_SDAR)) && event->attr.exclude_kernel)
|
||||||
*addrp = 0;
|
*addrp = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -477,7 +477,7 @@ static void power_pmu_bhrb_read(struct perf_event *event, struct cpu_hw_events *
|
|||||||
* addresses, hence include a check before filtering code
|
* addresses, hence include a check before filtering code
|
||||||
*/
|
*/
|
||||||
if (!(ppmu->flags & PPMU_ARCH_31) &&
|
if (!(ppmu->flags & PPMU_ARCH_31) &&
|
||||||
is_kernel_addr(addr) && perf_allow_kernel(&event->attr) != 0)
|
is_kernel_addr(addr) && event->attr.exclude_kernel)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* Branches are read most recent first (ie. mfbhrb 0 is
|
/* Branches are read most recent first (ie. mfbhrb 0 is
|
||||||
@@ -2112,7 +2112,17 @@ static void record_and_restart(struct perf_event *event, unsigned long val,
|
|||||||
left += period;
|
left += period;
|
||||||
if (left <= 0)
|
if (left <= 0)
|
||||||
left = period;
|
left = period;
|
||||||
record = siar_valid(regs);
|
|
||||||
|
/*
|
||||||
|
* If address is not requested in the sample via
|
||||||
|
* PERF_SAMPLE_IP, just record that sample irrespective
|
||||||
|
* of SIAR valid check.
|
||||||
|
*/
|
||||||
|
if (event->attr.sample_type & PERF_SAMPLE_IP)
|
||||||
|
record = siar_valid(regs);
|
||||||
|
else
|
||||||
|
record = 1;
|
||||||
|
|
||||||
event->hw.last_period = event->hw.sample_period;
|
event->hw.last_period = event->hw.sample_period;
|
||||||
}
|
}
|
||||||
if (left < 0x80000000LL)
|
if (left < 0x80000000LL)
|
||||||
@@ -2130,9 +2140,10 @@ static void record_and_restart(struct perf_event *event, unsigned long val,
|
|||||||
* MMCR2. Check attr.exclude_kernel and address to drop the sample in
|
* MMCR2. Check attr.exclude_kernel and address to drop the sample in
|
||||||
* these cases.
|
* these cases.
|
||||||
*/
|
*/
|
||||||
if (event->attr.exclude_kernel && record)
|
if (event->attr.exclude_kernel &&
|
||||||
if (is_kernel_addr(mfspr(SPRN_SIAR)))
|
(event->attr.sample_type & PERF_SAMPLE_IP) &&
|
||||||
record = 0;
|
is_kernel_addr(mfspr(SPRN_SIAR)))
|
||||||
|
record = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Finally record data if requested.
|
* Finally record data if requested.
|
||||||
|
@@ -4,6 +4,7 @@
|
|||||||
* Copyright 2006-2007 Michael Ellerman, IBM Corp.
|
* Copyright 2006-2007 Michael Ellerman, IBM Corp.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <linux/crash_dump.h>
|
||||||
#include <linux/device.h>
|
#include <linux/device.h>
|
||||||
#include <linux/irq.h>
|
#include <linux/irq.h>
|
||||||
#include <linux/msi.h>
|
#include <linux/msi.h>
|
||||||
@@ -458,8 +459,28 @@ again:
|
|||||||
return hwirq;
|
return hwirq;
|
||||||
}
|
}
|
||||||
|
|
||||||
virq = irq_create_mapping_affinity(NULL, hwirq,
|
/*
|
||||||
entry->affinity);
|
* Depending on the number of online CPUs in the original
|
||||||
|
* kernel, it is likely for CPU #0 to be offline in a kdump
|
||||||
|
* kernel. The associated IRQs in the affinity mappings
|
||||||
|
* provided by irq_create_affinity_masks() are thus not
|
||||||
|
* started by irq_startup(), as per-design for managed IRQs.
|
||||||
|
* This can be a problem with multi-queue block devices driven
|
||||||
|
* by blk-mq : such a non-started IRQ is very likely paired
|
||||||
|
* with the single queue enforced by blk-mq during kdump (see
|
||||||
|
* blk_mq_alloc_tag_set()). This causes the device to remain
|
||||||
|
* silent and likely hangs the guest at some point.
|
||||||
|
*
|
||||||
|
* We don't really care for fine-grained affinity when doing
|
||||||
|
* kdump actually : simply ignore the pre-computed affinity
|
||||||
|
* masks in this case and let the default mask with all CPUs
|
||||||
|
* be used when creating the IRQ mappings.
|
||||||
|
*/
|
||||||
|
if (is_kdump_kernel())
|
||||||
|
virq = irq_create_mapping(NULL, hwirq);
|
||||||
|
else
|
||||||
|
virq = irq_create_mapping_affinity(NULL, hwirq,
|
||||||
|
entry->affinity);
|
||||||
|
|
||||||
if (!virq) {
|
if (!virq) {
|
||||||
pr_debug("rtas_msi: Failed mapping hwirq %d\n", hwirq);
|
pr_debug("rtas_msi: Failed mapping hwirq %d\n", hwirq);
|
||||||
|
@@ -775,7 +775,7 @@ static int smp_add_core(struct sclp_core_entry *core, cpumask_t *avail,
|
|||||||
static int __smp_rescan_cpus(struct sclp_core_info *info, bool early)
|
static int __smp_rescan_cpus(struct sclp_core_info *info, bool early)
|
||||||
{
|
{
|
||||||
struct sclp_core_entry *core;
|
struct sclp_core_entry *core;
|
||||||
cpumask_t avail;
|
static cpumask_t avail;
|
||||||
bool configured;
|
bool configured;
|
||||||
u16 core_id;
|
u16 core_id;
|
||||||
int nr, i;
|
int nr, i;
|
||||||
|
@@ -57,36 +57,40 @@ static inline int sparc_validate_prot(unsigned long prot, unsigned long addr)
|
|||||||
{
|
{
|
||||||
if (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC | PROT_SEM | PROT_ADI))
|
if (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC | PROT_SEM | PROT_ADI))
|
||||||
return 0;
|
return 0;
|
||||||
if (prot & PROT_ADI) {
|
|
||||||
if (!adi_capable())
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (addr) {
|
|
||||||
struct vm_area_struct *vma;
|
|
||||||
|
|
||||||
vma = find_vma(current->mm, addr);
|
|
||||||
if (vma) {
|
|
||||||
/* ADI can not be enabled on PFN
|
|
||||||
* mapped pages
|
|
||||||
*/
|
|
||||||
if (vma->vm_flags & (VM_PFNMAP | VM_MIXEDMAP))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* Mergeable pages can become unmergeable
|
|
||||||
* if ADI is enabled on them even if they
|
|
||||||
* have identical data on them. This can be
|
|
||||||
* because ADI enabled pages with identical
|
|
||||||
* data may still not have identical ADI
|
|
||||||
* tags on them. Disallow ADI on mergeable
|
|
||||||
* pages.
|
|
||||||
*/
|
|
||||||
if (vma->vm_flags & VM_MERGEABLE)
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define arch_validate_flags(vm_flags) arch_validate_flags(vm_flags)
|
||||||
|
/* arch_validate_flags() - Ensure combination of flags is valid for a
|
||||||
|
* VMA.
|
||||||
|
*/
|
||||||
|
static inline bool arch_validate_flags(unsigned long vm_flags)
|
||||||
|
{
|
||||||
|
/* If ADI is being enabled on this VMA, check for ADI
|
||||||
|
* capability on the platform and ensure VMA is suitable
|
||||||
|
* for ADI
|
||||||
|
*/
|
||||||
|
if (vm_flags & VM_SPARC_ADI) {
|
||||||
|
if (!adi_capable())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
/* ADI can not be enabled on PFN mapped pages */
|
||||||
|
if (vm_flags & (VM_PFNMAP | VM_MIXEDMAP))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
/* Mergeable pages can become unmergeable
|
||||||
|
* if ADI is enabled on them even if they
|
||||||
|
* have identical data on them. This can be
|
||||||
|
* because ADI enabled pages with identical
|
||||||
|
* data may still not have identical ADI
|
||||||
|
* tags on them. Disallow ADI on mergeable
|
||||||
|
* pages.
|
||||||
|
*/
|
||||||
|
if (vm_flags & VM_MERGEABLE)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
#endif /* CONFIG_SPARC64 */
|
#endif /* CONFIG_SPARC64 */
|
||||||
|
|
||||||
#endif /* __ASSEMBLY__ */
|
#endif /* __ASSEMBLY__ */
|
||||||
|
@@ -197,6 +197,9 @@ unsigned long __init bootmem_init(unsigned long *pages_avail)
|
|||||||
size = memblock_phys_mem_size() - memblock_reserved_size();
|
size = memblock_phys_mem_size() - memblock_reserved_size();
|
||||||
*pages_avail = (size >> PAGE_SHIFT) - high_pages;
|
*pages_avail = (size >> PAGE_SHIFT) - high_pages;
|
||||||
|
|
||||||
|
/* Only allow low memory to be allocated via memblock allocation */
|
||||||
|
memblock_set_current_limit(max_low_pfn << PAGE_SHIFT);
|
||||||
|
|
||||||
return max_pfn;
|
return max_pfn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -128,7 +128,8 @@ static noinstr bool __do_fast_syscall_32(struct pt_regs *regs)
|
|||||||
regs->ax = -EFAULT;
|
regs->ax = -EFAULT;
|
||||||
|
|
||||||
instrumentation_end();
|
instrumentation_end();
|
||||||
syscall_exit_to_user_mode(regs);
|
local_irq_disable();
|
||||||
|
irqentry_exit_to_user_mode(regs);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -213,40 +214,6 @@ SYSCALL_DEFINE0(ni_syscall)
|
|||||||
return -ENOSYS;
|
return -ENOSYS;
|
||||||
}
|
}
|
||||||
|
|
||||||
noinstr bool idtentry_enter_nmi(struct pt_regs *regs)
|
|
||||||
{
|
|
||||||
bool irq_state = lockdep_hardirqs_enabled();
|
|
||||||
|
|
||||||
__nmi_enter();
|
|
||||||
lockdep_hardirqs_off(CALLER_ADDR0);
|
|
||||||
lockdep_hardirq_enter();
|
|
||||||
rcu_nmi_enter();
|
|
||||||
|
|
||||||
instrumentation_begin();
|
|
||||||
trace_hardirqs_off_finish();
|
|
||||||
ftrace_nmi_enter();
|
|
||||||
instrumentation_end();
|
|
||||||
|
|
||||||
return irq_state;
|
|
||||||
}
|
|
||||||
|
|
||||||
noinstr void idtentry_exit_nmi(struct pt_regs *regs, bool restore)
|
|
||||||
{
|
|
||||||
instrumentation_begin();
|
|
||||||
ftrace_nmi_exit();
|
|
||||||
if (restore) {
|
|
||||||
trace_hardirqs_on_prepare();
|
|
||||||
lockdep_hardirqs_on_prepare(CALLER_ADDR0);
|
|
||||||
}
|
|
||||||
instrumentation_end();
|
|
||||||
|
|
||||||
rcu_nmi_exit();
|
|
||||||
lockdep_hardirq_exit();
|
|
||||||
if (restore)
|
|
||||||
lockdep_hardirqs_on(CALLER_ADDR0);
|
|
||||||
__nmi_exit();
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef CONFIG_XEN_PV
|
#ifdef CONFIG_XEN_PV
|
||||||
#ifndef CONFIG_PREEMPTION
|
#ifndef CONFIG_PREEMPTION
|
||||||
/*
|
/*
|
||||||
|
@@ -210,6 +210,8 @@ SYM_CODE_START(entry_SYSCALL_compat)
|
|||||||
/* Switch to the kernel stack */
|
/* Switch to the kernel stack */
|
||||||
movq PER_CPU_VAR(cpu_current_top_of_stack), %rsp
|
movq PER_CPU_VAR(cpu_current_top_of_stack), %rsp
|
||||||
|
|
||||||
|
SYM_INNER_LABEL(entry_SYSCALL_compat_safe_stack, SYM_L_GLOBAL)
|
||||||
|
|
||||||
/* Construct struct pt_regs on stack */
|
/* Construct struct pt_regs on stack */
|
||||||
pushq $__USER32_DS /* pt_regs->ss */
|
pushq $__USER32_DS /* pt_regs->ss */
|
||||||
pushq %r8 /* pt_regs->sp */
|
pushq %r8 /* pt_regs->sp */
|
||||||
|
@@ -3565,8 +3565,10 @@ static int intel_pmu_hw_config(struct perf_event *event)
|
|||||||
if (!(event->attr.freq || (event->attr.wakeup_events && !event->attr.watermark))) {
|
if (!(event->attr.freq || (event->attr.wakeup_events && !event->attr.watermark))) {
|
||||||
event->hw.flags |= PERF_X86_EVENT_AUTO_RELOAD;
|
event->hw.flags |= PERF_X86_EVENT_AUTO_RELOAD;
|
||||||
if (!(event->attr.sample_type &
|
if (!(event->attr.sample_type &
|
||||||
~intel_pmu_large_pebs_flags(event)))
|
~intel_pmu_large_pebs_flags(event))) {
|
||||||
event->hw.flags |= PERF_X86_EVENT_LARGE_PEBS;
|
event->hw.flags |= PERF_X86_EVENT_LARGE_PEBS;
|
||||||
|
event->attach_state |= PERF_ATTACH_SCHED_CB;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (x86_pmu.pebs_aliases)
|
if (x86_pmu.pebs_aliases)
|
||||||
x86_pmu.pebs_aliases(event);
|
x86_pmu.pebs_aliases(event);
|
||||||
@@ -3579,6 +3581,7 @@ static int intel_pmu_hw_config(struct perf_event *event)
|
|||||||
ret = intel_pmu_setup_lbr_filter(event);
|
ret = intel_pmu_setup_lbr_filter(event);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
event->attach_state |= PERF_ATTACH_SCHED_CB;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* BTS is set up earlier in this path, so don't account twice
|
* BTS is set up earlier in this path, so don't account twice
|
||||||
|
@@ -11,9 +11,6 @@
|
|||||||
|
|
||||||
#include <asm/irq_stack.h>
|
#include <asm/irq_stack.h>
|
||||||
|
|
||||||
bool idtentry_enter_nmi(struct pt_regs *regs);
|
|
||||||
void idtentry_exit_nmi(struct pt_regs *regs, bool irq_state);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* DECLARE_IDTENTRY - Declare functions for simple IDT entry points
|
* DECLARE_IDTENTRY - Declare functions for simple IDT entry points
|
||||||
* No error code pushed by hardware
|
* No error code pushed by hardware
|
||||||
|
@@ -23,6 +23,8 @@ unsigned long insn_get_seg_base(struct pt_regs *regs, int seg_reg_idx);
|
|||||||
int insn_get_code_seg_params(struct pt_regs *regs);
|
int insn_get_code_seg_params(struct pt_regs *regs);
|
||||||
int insn_fetch_from_user(struct pt_regs *regs,
|
int insn_fetch_from_user(struct pt_regs *regs,
|
||||||
unsigned char buf[MAX_INSN_SIZE]);
|
unsigned char buf[MAX_INSN_SIZE]);
|
||||||
|
int insn_fetch_from_user_inatomic(struct pt_regs *regs,
|
||||||
|
unsigned char buf[MAX_INSN_SIZE]);
|
||||||
bool insn_decode(struct insn *insn, struct pt_regs *regs,
|
bool insn_decode(struct insn *insn, struct pt_regs *regs,
|
||||||
unsigned char buf[MAX_INSN_SIZE], int buf_size);
|
unsigned char buf[MAX_INSN_SIZE], int buf_size);
|
||||||
|
|
||||||
|
@@ -25,6 +25,7 @@ void __end_SYSENTER_singlestep_region(void);
|
|||||||
void entry_SYSENTER_compat(void);
|
void entry_SYSENTER_compat(void);
|
||||||
void __end_entry_SYSENTER_compat(void);
|
void __end_entry_SYSENTER_compat(void);
|
||||||
void entry_SYSCALL_compat(void);
|
void entry_SYSCALL_compat(void);
|
||||||
|
void entry_SYSCALL_compat_safe_stack(void);
|
||||||
void entry_INT80_compat(void);
|
void entry_INT80_compat(void);
|
||||||
#ifdef CONFIG_XEN_PV
|
#ifdef CONFIG_XEN_PV
|
||||||
void xen_entry_INT80_compat(void);
|
void xen_entry_INT80_compat(void);
|
||||||
|
@@ -94,6 +94,8 @@ struct pt_regs {
|
|||||||
#include <asm/paravirt_types.h>
|
#include <asm/paravirt_types.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <asm/proto.h>
|
||||||
|
|
||||||
struct cpuinfo_x86;
|
struct cpuinfo_x86;
|
||||||
struct task_struct;
|
struct task_struct;
|
||||||
|
|
||||||
@@ -175,6 +177,19 @@ static inline bool any_64bit_mode(struct pt_regs *regs)
|
|||||||
#ifdef CONFIG_X86_64
|
#ifdef CONFIG_X86_64
|
||||||
#define current_user_stack_pointer() current_pt_regs()->sp
|
#define current_user_stack_pointer() current_pt_regs()->sp
|
||||||
#define compat_user_stack_pointer() current_pt_regs()->sp
|
#define compat_user_stack_pointer() current_pt_regs()->sp
|
||||||
|
|
||||||
|
static inline bool ip_within_syscall_gap(struct pt_regs *regs)
|
||||||
|
{
|
||||||
|
bool ret = (regs->ip >= (unsigned long)entry_SYSCALL_64 &&
|
||||||
|
regs->ip < (unsigned long)entry_SYSCALL_64_safe_stack);
|
||||||
|
|
||||||
|
#ifdef CONFIG_IA32_EMULATION
|
||||||
|
ret = ret || (regs->ip >= (unsigned long)entry_SYSCALL_compat &&
|
||||||
|
regs->ip < (unsigned long)entry_SYSCALL_compat_safe_stack);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static inline unsigned long kernel_stack_pointer(struct pt_regs *regs)
|
static inline unsigned long kernel_stack_pointer(struct pt_regs *regs)
|
||||||
|
@@ -1986,7 +1986,7 @@ void (*machine_check_vector)(struct pt_regs *) = unexpected_machine_check;
|
|||||||
|
|
||||||
static __always_inline void exc_machine_check_kernel(struct pt_regs *regs)
|
static __always_inline void exc_machine_check_kernel(struct pt_regs *regs)
|
||||||
{
|
{
|
||||||
bool irq_state;
|
irqentry_state_t irq_state;
|
||||||
|
|
||||||
WARN_ON_ONCE(user_mode(regs));
|
WARN_ON_ONCE(user_mode(regs));
|
||||||
|
|
||||||
@@ -1998,7 +1998,7 @@ static __always_inline void exc_machine_check_kernel(struct pt_regs *regs)
|
|||||||
mce_check_crashing_cpu())
|
mce_check_crashing_cpu())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
irq_state = idtentry_enter_nmi(regs);
|
irq_state = irqentry_nmi_enter(regs);
|
||||||
/*
|
/*
|
||||||
* The call targets are marked noinstr, but objtool can't figure
|
* The call targets are marked noinstr, but objtool can't figure
|
||||||
* that out because it's an indirect call. Annotate it.
|
* that out because it's an indirect call. Annotate it.
|
||||||
@@ -2009,7 +2009,7 @@ static __always_inline void exc_machine_check_kernel(struct pt_regs *regs)
|
|||||||
if (regs->flags & X86_EFLAGS_IF)
|
if (regs->flags & X86_EFLAGS_IF)
|
||||||
trace_hardirqs_on_prepare();
|
trace_hardirqs_on_prepare();
|
||||||
instrumentation_end();
|
instrumentation_end();
|
||||||
idtentry_exit_nmi(regs, irq_state);
|
irqentry_nmi_exit(regs, irq_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
static __always_inline void exc_machine_check_user(struct pt_regs *regs)
|
static __always_inline void exc_machine_check_user(struct pt_regs *regs)
|
||||||
|
@@ -269,21 +269,20 @@ static void __init kvmclock_init_mem(void)
|
|||||||
|
|
||||||
static int __init kvm_setup_vsyscall_timeinfo(void)
|
static int __init kvm_setup_vsyscall_timeinfo(void)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_X86_64
|
|
||||||
u8 flags;
|
|
||||||
|
|
||||||
if (!per_cpu(hv_clock_per_cpu, 0) || !kvmclock_vsyscall)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
flags = pvclock_read_flags(&hv_clock_boot[0].pvti);
|
|
||||||
if (!(flags & PVCLOCK_TSC_STABLE_BIT))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
kvm_clock.vdso_clock_mode = VDSO_CLOCKMODE_PVCLOCK;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
kvmclock_init_mem();
|
kvmclock_init_mem();
|
||||||
|
|
||||||
|
#ifdef CONFIG_X86_64
|
||||||
|
if (per_cpu(hv_clock_per_cpu, 0) && kvmclock_vsyscall) {
|
||||||
|
u8 flags;
|
||||||
|
|
||||||
|
flags = pvclock_read_flags(&hv_clock_boot[0].pvti);
|
||||||
|
if (!(flags & PVCLOCK_TSC_STABLE_BIT))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
kvm_clock.vdso_clock_mode = VDSO_CLOCKMODE_PVCLOCK;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
early_initcall(kvm_setup_vsyscall_timeinfo);
|
early_initcall(kvm_setup_vsyscall_timeinfo);
|
||||||
|
@@ -475,7 +475,7 @@ static DEFINE_PER_CPU(unsigned long, nmi_dr7);
|
|||||||
|
|
||||||
DEFINE_IDTENTRY_RAW(exc_nmi)
|
DEFINE_IDTENTRY_RAW(exc_nmi)
|
||||||
{
|
{
|
||||||
bool irq_state;
|
irqentry_state_t irq_state;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Re-enable NMIs right here when running as an SEV-ES guest. This might
|
* Re-enable NMIs right here when running as an SEV-ES guest. This might
|
||||||
@@ -502,14 +502,14 @@ nmi_restart:
|
|||||||
|
|
||||||
this_cpu_write(nmi_dr7, local_db_save());
|
this_cpu_write(nmi_dr7, local_db_save());
|
||||||
|
|
||||||
irq_state = idtentry_enter_nmi(regs);
|
irq_state = irqentry_nmi_enter(regs);
|
||||||
|
|
||||||
inc_irq_stat(__nmi_count);
|
inc_irq_stat(__nmi_count);
|
||||||
|
|
||||||
if (!ignore_nmis)
|
if (!ignore_nmis)
|
||||||
default_do_nmi(regs);
|
default_do_nmi(regs);
|
||||||
|
|
||||||
idtentry_exit_nmi(regs, irq_state);
|
irqentry_nmi_exit(regs, irq_state);
|
||||||
|
|
||||||
local_db_restore(this_cpu_read(nmi_dr7));
|
local_db_restore(this_cpu_read(nmi_dr7));
|
||||||
|
|
||||||
|
@@ -121,8 +121,18 @@ static void __init setup_vc_stacks(int cpu)
|
|||||||
cea_set_pte((void *)vaddr, pa, PAGE_KERNEL);
|
cea_set_pte((void *)vaddr, pa, PAGE_KERNEL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static __always_inline bool on_vc_stack(unsigned long sp)
|
static __always_inline bool on_vc_stack(struct pt_regs *regs)
|
||||||
{
|
{
|
||||||
|
unsigned long sp = regs->sp;
|
||||||
|
|
||||||
|
/* User-mode RSP is not trusted */
|
||||||
|
if (user_mode(regs))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
/* SYSCALL gap still has user-mode RSP */
|
||||||
|
if (ip_within_syscall_gap(regs))
|
||||||
|
return false;
|
||||||
|
|
||||||
return ((sp >= __this_cpu_ist_bottom_va(VC)) && (sp < __this_cpu_ist_top_va(VC)));
|
return ((sp >= __this_cpu_ist_bottom_va(VC)) && (sp < __this_cpu_ist_top_va(VC)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -144,7 +154,7 @@ void noinstr __sev_es_ist_enter(struct pt_regs *regs)
|
|||||||
old_ist = __this_cpu_read(cpu_tss_rw.x86_tss.ist[IST_INDEX_VC]);
|
old_ist = __this_cpu_read(cpu_tss_rw.x86_tss.ist[IST_INDEX_VC]);
|
||||||
|
|
||||||
/* Make room on the IST stack */
|
/* Make room on the IST stack */
|
||||||
if (on_vc_stack(regs->sp))
|
if (on_vc_stack(regs))
|
||||||
new_ist = ALIGN_DOWN(regs->sp, 8) - sizeof(old_ist);
|
new_ist = ALIGN_DOWN(regs->sp, 8) - sizeof(old_ist);
|
||||||
else
|
else
|
||||||
new_ist = old_ist - sizeof(old_ist);
|
new_ist = old_ist - sizeof(old_ist);
|
||||||
@@ -248,7 +258,7 @@ static enum es_result vc_decode_insn(struct es_em_ctxt *ctxt)
|
|||||||
int res;
|
int res;
|
||||||
|
|
||||||
if (user_mode(ctxt->regs)) {
|
if (user_mode(ctxt->regs)) {
|
||||||
res = insn_fetch_from_user(ctxt->regs, buffer);
|
res = insn_fetch_from_user_inatomic(ctxt->regs, buffer);
|
||||||
if (!res) {
|
if (!res) {
|
||||||
ctxt->fi.vector = X86_TRAP_PF;
|
ctxt->fi.vector = X86_TRAP_PF;
|
||||||
ctxt->fi.error_code = X86_PF_INSTR | X86_PF_USER;
|
ctxt->fi.error_code = X86_PF_INSTR | X86_PF_USER;
|
||||||
@@ -1248,13 +1258,12 @@ static __always_inline bool on_vc_fallback_stack(struct pt_regs *regs)
|
|||||||
DEFINE_IDTENTRY_VC_SAFE_STACK(exc_vmm_communication)
|
DEFINE_IDTENTRY_VC_SAFE_STACK(exc_vmm_communication)
|
||||||
{
|
{
|
||||||
struct sev_es_runtime_data *data = this_cpu_read(runtime_data);
|
struct sev_es_runtime_data *data = this_cpu_read(runtime_data);
|
||||||
|
irqentry_state_t irq_state;
|
||||||
struct ghcb_state state;
|
struct ghcb_state state;
|
||||||
struct es_em_ctxt ctxt;
|
struct es_em_ctxt ctxt;
|
||||||
enum es_result result;
|
enum es_result result;
|
||||||
struct ghcb *ghcb;
|
struct ghcb *ghcb;
|
||||||
|
|
||||||
lockdep_assert_irqs_disabled();
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Handle #DB before calling into !noinstr code to avoid recursive #DB.
|
* Handle #DB before calling into !noinstr code to avoid recursive #DB.
|
||||||
*/
|
*/
|
||||||
@@ -1263,6 +1272,8 @@ DEFINE_IDTENTRY_VC_SAFE_STACK(exc_vmm_communication)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
irq_state = irqentry_nmi_enter(regs);
|
||||||
|
lockdep_assert_irqs_disabled();
|
||||||
instrumentation_begin();
|
instrumentation_begin();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1325,6 +1336,7 @@ DEFINE_IDTENTRY_VC_SAFE_STACK(exc_vmm_communication)
|
|||||||
|
|
||||||
out:
|
out:
|
||||||
instrumentation_end();
|
instrumentation_end();
|
||||||
|
irqentry_nmi_exit(regs, irq_state);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@@ -406,7 +406,7 @@ DEFINE_IDTENTRY_DF(exc_double_fault)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
idtentry_enter_nmi(regs);
|
irqentry_nmi_enter(regs);
|
||||||
instrumentation_begin();
|
instrumentation_begin();
|
||||||
notify_die(DIE_TRAP, str, regs, error_code, X86_TRAP_DF, SIGSEGV);
|
notify_die(DIE_TRAP, str, regs, error_code, X86_TRAP_DF, SIGSEGV);
|
||||||
|
|
||||||
@@ -652,12 +652,13 @@ DEFINE_IDTENTRY_RAW(exc_int3)
|
|||||||
instrumentation_end();
|
instrumentation_end();
|
||||||
irqentry_exit_to_user_mode(regs);
|
irqentry_exit_to_user_mode(regs);
|
||||||
} else {
|
} else {
|
||||||
bool irq_state = idtentry_enter_nmi(regs);
|
irqentry_state_t irq_state = irqentry_nmi_enter(regs);
|
||||||
|
|
||||||
instrumentation_begin();
|
instrumentation_begin();
|
||||||
if (!do_int3(regs))
|
if (!do_int3(regs))
|
||||||
die("int3", regs, 0);
|
die("int3", regs, 0);
|
||||||
instrumentation_end();
|
instrumentation_end();
|
||||||
idtentry_exit_nmi(regs, irq_state);
|
irqentry_nmi_exit(regs, irq_state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -686,8 +687,7 @@ asmlinkage __visible noinstr struct pt_regs *vc_switch_off_ist(struct pt_regs *r
|
|||||||
* In the SYSCALL entry path the RSP value comes from user-space - don't
|
* In the SYSCALL entry path the RSP value comes from user-space - don't
|
||||||
* trust it and switch to the current kernel stack
|
* trust it and switch to the current kernel stack
|
||||||
*/
|
*/
|
||||||
if (regs->ip >= (unsigned long)entry_SYSCALL_64 &&
|
if (ip_within_syscall_gap(regs)) {
|
||||||
regs->ip < (unsigned long)entry_SYSCALL_64_safe_stack) {
|
|
||||||
sp = this_cpu_read(cpu_current_top_of_stack);
|
sp = this_cpu_read(cpu_current_top_of_stack);
|
||||||
goto sync;
|
goto sync;
|
||||||
}
|
}
|
||||||
@@ -852,7 +852,7 @@ static __always_inline void exc_debug_kernel(struct pt_regs *regs,
|
|||||||
* includes the entry stack is excluded for everything.
|
* includes the entry stack is excluded for everything.
|
||||||
*/
|
*/
|
||||||
unsigned long dr7 = local_db_save();
|
unsigned long dr7 = local_db_save();
|
||||||
bool irq_state = idtentry_enter_nmi(regs);
|
irqentry_state_t irq_state = irqentry_nmi_enter(regs);
|
||||||
instrumentation_begin();
|
instrumentation_begin();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -909,7 +909,7 @@ static __always_inline void exc_debug_kernel(struct pt_regs *regs,
|
|||||||
regs->flags &= ~X86_EFLAGS_TF;
|
regs->flags &= ~X86_EFLAGS_TF;
|
||||||
out:
|
out:
|
||||||
instrumentation_end();
|
instrumentation_end();
|
||||||
idtentry_exit_nmi(regs, irq_state);
|
irqentry_nmi_exit(regs, irq_state);
|
||||||
|
|
||||||
local_db_restore(dr7);
|
local_db_restore(dr7);
|
||||||
}
|
}
|
||||||
@@ -927,7 +927,7 @@ static __always_inline void exc_debug_user(struct pt_regs *regs,
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* NB: We can't easily clear DR7 here because
|
* NB: We can't easily clear DR7 here because
|
||||||
* idtentry_exit_to_usermode() can invoke ptrace, schedule, access
|
* irqentry_exit_to_usermode() can invoke ptrace, schedule, access
|
||||||
* user memory, etc. This means that a recursive #DB is possible. If
|
* user memory, etc. This means that a recursive #DB is possible. If
|
||||||
* this happens, that #DB will hit exc_debug_kernel() and clear DR7.
|
* this happens, that #DB will hit exc_debug_kernel() and clear DR7.
|
||||||
* Since we're not on the IST stack right now, everything will be
|
* Since we're not on the IST stack right now, everything will be
|
||||||
|
@@ -367,8 +367,8 @@ static bool deref_stack_regs(struct unwind_state *state, unsigned long addr,
|
|||||||
if (!stack_access_ok(state, addr, sizeof(struct pt_regs)))
|
if (!stack_access_ok(state, addr, sizeof(struct pt_regs)))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
*ip = regs->ip;
|
*ip = READ_ONCE_NOCHECK(regs->ip);
|
||||||
*sp = regs->sp;
|
*sp = READ_ONCE_NOCHECK(regs->sp);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -380,8 +380,8 @@ static bool deref_stack_iret_regs(struct unwind_state *state, unsigned long addr
|
|||||||
if (!stack_access_ok(state, addr, IRET_FRAME_SIZE))
|
if (!stack_access_ok(state, addr, IRET_FRAME_SIZE))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
*ip = regs->ip;
|
*ip = READ_ONCE_NOCHECK(regs->ip);
|
||||||
*sp = regs->sp;
|
*sp = READ_ONCE_NOCHECK(regs->sp);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -402,12 +402,12 @@ static bool get_reg(struct unwind_state *state, unsigned int reg_off,
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (state->full_regs) {
|
if (state->full_regs) {
|
||||||
*val = ((unsigned long *)state->regs)[reg];
|
*val = READ_ONCE_NOCHECK(((unsigned long *)state->regs)[reg]);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state->prev_regs) {
|
if (state->prev_regs) {
|
||||||
*val = ((unsigned long *)state->prev_regs)[reg];
|
*val = READ_ONCE_NOCHECK(((unsigned long *)state->prev_regs)[reg]);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1641,7 +1641,16 @@ static void apic_timer_expired(struct kvm_lapic *apic, bool from_timer_fn)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (kvm_use_posted_timer_interrupt(apic->vcpu)) {
|
if (kvm_use_posted_timer_interrupt(apic->vcpu)) {
|
||||||
kvm_wait_lapic_expire(vcpu);
|
/*
|
||||||
|
* Ensure the guest's timer has truly expired before posting an
|
||||||
|
* interrupt. Open code the relevant checks to avoid querying
|
||||||
|
* lapic_timer_int_injected(), which will be false since the
|
||||||
|
* interrupt isn't yet injected. Waiting until after injecting
|
||||||
|
* is not an option since that won't help a posted interrupt.
|
||||||
|
*/
|
||||||
|
if (vcpu->arch.apic->lapic_timer.expired_tscdeadline &&
|
||||||
|
vcpu->arch.apic->lapic_timer.timer_advance_ns)
|
||||||
|
__kvm_wait_lapic_expire(vcpu);
|
||||||
kvm_apic_inject_pending_timer_irqs(apic);
|
kvm_apic_inject_pending_timer_irqs(apic);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@@ -1415,6 +1415,25 @@ void __user *insn_get_addr_ref(struct insn *insn, struct pt_regs *regs)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static unsigned long insn_get_effective_ip(struct pt_regs *regs)
|
||||||
|
{
|
||||||
|
unsigned long seg_base = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If not in user-space long mode, a custom code segment could be in
|
||||||
|
* use. This is true in protected mode (if the process defined a local
|
||||||
|
* descriptor table), or virtual-8086 mode. In most of the cases
|
||||||
|
* seg_base will be zero as in USER_CS.
|
||||||
|
*/
|
||||||
|
if (!user_64bit_mode(regs)) {
|
||||||
|
seg_base = insn_get_seg_base(regs, INAT_SEG_REG_CS);
|
||||||
|
if (seg_base == -1L)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return seg_base + regs->ip;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* insn_fetch_from_user() - Copy instruction bytes from user-space memory
|
* insn_fetch_from_user() - Copy instruction bytes from user-space memory
|
||||||
* @regs: Structure with register values as seen when entering kernel mode
|
* @regs: Structure with register values as seen when entering kernel mode
|
||||||
@@ -1431,24 +1450,43 @@ void __user *insn_get_addr_ref(struct insn *insn, struct pt_regs *regs)
|
|||||||
*/
|
*/
|
||||||
int insn_fetch_from_user(struct pt_regs *regs, unsigned char buf[MAX_INSN_SIZE])
|
int insn_fetch_from_user(struct pt_regs *regs, unsigned char buf[MAX_INSN_SIZE])
|
||||||
{
|
{
|
||||||
unsigned long seg_base = 0;
|
unsigned long ip;
|
||||||
int not_copied;
|
int not_copied;
|
||||||
|
|
||||||
/*
|
ip = insn_get_effective_ip(regs);
|
||||||
* If not in user-space long mode, a custom code segment could be in
|
if (!ip)
|
||||||
* use. This is true in protected mode (if the process defined a local
|
return 0;
|
||||||
* descriptor table), or virtual-8086 mode. In most of the cases
|
|
||||||
* seg_base will be zero as in USER_CS.
|
|
||||||
*/
|
|
||||||
if (!user_64bit_mode(regs)) {
|
|
||||||
seg_base = insn_get_seg_base(regs, INAT_SEG_REG_CS);
|
|
||||||
if (seg_base == -1L)
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
not_copied = copy_from_user(buf, (void __user *)ip, MAX_INSN_SIZE);
|
||||||
|
|
||||||
not_copied = copy_from_user(buf, (void __user *)(seg_base + regs->ip),
|
return MAX_INSN_SIZE - not_copied;
|
||||||
MAX_INSN_SIZE);
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* insn_fetch_from_user_inatomic() - Copy instruction bytes from user-space memory
|
||||||
|
* while in atomic code
|
||||||
|
* @regs: Structure with register values as seen when entering kernel mode
|
||||||
|
* @buf: Array to store the fetched instruction
|
||||||
|
*
|
||||||
|
* Gets the linear address of the instruction and copies the instruction bytes
|
||||||
|
* to the buf. This function must be used in atomic context.
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
*
|
||||||
|
* Number of instruction bytes copied.
|
||||||
|
*
|
||||||
|
* 0 if nothing was copied.
|
||||||
|
*/
|
||||||
|
int insn_fetch_from_user_inatomic(struct pt_regs *regs, unsigned char buf[MAX_INSN_SIZE])
|
||||||
|
{
|
||||||
|
unsigned long ip;
|
||||||
|
int not_copied;
|
||||||
|
|
||||||
|
ip = insn_get_effective_ip(regs);
|
||||||
|
if (!ip)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
not_copied = __copy_from_user_inatomic(buf, (void __user *)ip, MAX_INSN_SIZE);
|
||||||
|
|
||||||
return MAX_INSN_SIZE - not_copied;
|
return MAX_INSN_SIZE - not_copied;
|
||||||
}
|
}
|
||||||
|
@@ -318,6 +318,22 @@ int blkdev_report_zones_ioctl(struct block_device *bdev, fmode_t mode,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int blkdev_truncate_zone_range(struct block_device *bdev, fmode_t mode,
|
||||||
|
const struct blk_zone_range *zrange)
|
||||||
|
{
|
||||||
|
loff_t start, end;
|
||||||
|
|
||||||
|
if (zrange->sector + zrange->nr_sectors <= zrange->sector ||
|
||||||
|
zrange->sector + zrange->nr_sectors > get_capacity(bdev->bd_disk))
|
||||||
|
/* Out of range */
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
start = zrange->sector << SECTOR_SHIFT;
|
||||||
|
end = ((zrange->sector + zrange->nr_sectors) << SECTOR_SHIFT) - 1;
|
||||||
|
|
||||||
|
return truncate_bdev_range(bdev, mode, start, end);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* BLKRESETZONE, BLKOPENZONE, BLKCLOSEZONE and BLKFINISHZONE ioctl processing.
|
* BLKRESETZONE, BLKOPENZONE, BLKCLOSEZONE and BLKFINISHZONE ioctl processing.
|
||||||
* Called from blkdev_ioctl.
|
* Called from blkdev_ioctl.
|
||||||
@@ -329,6 +345,7 @@ int blkdev_zone_mgmt_ioctl(struct block_device *bdev, fmode_t mode,
|
|||||||
struct request_queue *q;
|
struct request_queue *q;
|
||||||
struct blk_zone_range zrange;
|
struct blk_zone_range zrange;
|
||||||
enum req_opf op;
|
enum req_opf op;
|
||||||
|
int ret;
|
||||||
|
|
||||||
if (!argp)
|
if (!argp)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
@@ -352,6 +369,11 @@ int blkdev_zone_mgmt_ioctl(struct block_device *bdev, fmode_t mode,
|
|||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case BLKRESETZONE:
|
case BLKRESETZONE:
|
||||||
op = REQ_OP_ZONE_RESET;
|
op = REQ_OP_ZONE_RESET;
|
||||||
|
|
||||||
|
/* Invalidate the page cache, including dirty pages. */
|
||||||
|
ret = blkdev_truncate_zone_range(bdev, mode, &zrange);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
break;
|
break;
|
||||||
case BLKOPENZONE:
|
case BLKOPENZONE:
|
||||||
op = REQ_OP_ZONE_OPEN;
|
op = REQ_OP_ZONE_OPEN;
|
||||||
@@ -366,8 +388,20 @@ int blkdev_zone_mgmt_ioctl(struct block_device *bdev, fmode_t mode,
|
|||||||
return -ENOTTY;
|
return -ENOTTY;
|
||||||
}
|
}
|
||||||
|
|
||||||
return blkdev_zone_mgmt(bdev, op, zrange.sector, zrange.nr_sectors,
|
ret = blkdev_zone_mgmt(bdev, op, zrange.sector, zrange.nr_sectors,
|
||||||
GFP_KERNEL);
|
GFP_KERNEL);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Invalidate the page cache again for zone reset: writes can only be
|
||||||
|
* direct for zoned devices so concurrent writes would not add any page
|
||||||
|
* to the page cache after/during reset. The page cache may be filled
|
||||||
|
* again due to concurrent reads though and dropping the pages for
|
||||||
|
* these is fine.
|
||||||
|
*/
|
||||||
|
if (!ret && cmd == BLKRESETZONE)
|
||||||
|
ret = blkdev_truncate_zone_range(bdev, mode, &zrange);
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline unsigned long *blk_alloc_zone_bitmap(int node,
|
static inline unsigned long *blk_alloc_zone_bitmap(int node,
|
||||||
|
@@ -772,7 +772,7 @@ config CRYPTO_POLY1305_X86_64
|
|||||||
|
|
||||||
config CRYPTO_POLY1305_MIPS
|
config CRYPTO_POLY1305_MIPS
|
||||||
tristate "Poly1305 authenticator algorithm (MIPS optimized)"
|
tristate "Poly1305 authenticator algorithm (MIPS optimized)"
|
||||||
depends on CPU_MIPS32 || (CPU_MIPS64 && 64BIT)
|
depends on MIPS
|
||||||
select CRYPTO_ARCH_HAVE_LIB_POLY1305
|
select CRYPTO_ARCH_HAVE_LIB_POLY1305
|
||||||
|
|
||||||
config CRYPTO_MD4
|
config CRYPTO_MD4
|
||||||
|
@@ -290,20 +290,20 @@ static ssize_t state_store(struct device *dev, struct device_attribute *attr,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* phys_device is a bad name for this. What I really want
|
* Legacy interface that we cannot remove: s390x exposes the storage increment
|
||||||
* is a way to differentiate between memory ranges that
|
* covered by a memory block, allowing for identifying which memory blocks
|
||||||
* are part of physical devices that constitute
|
* comprise a storage increment. Since a memory block spans complete
|
||||||
* a complete removable unit or fru.
|
* storage increments nowadays, this interface is basically unused. Other
|
||||||
* i.e. do these ranges belong to the same physical device,
|
* archs never exposed != 0.
|
||||||
* s.t. if I offline all of these sections I can then
|
|
||||||
* remove the physical device?
|
|
||||||
*/
|
*/
|
||||||
static ssize_t phys_device_show(struct device *dev,
|
static ssize_t phys_device_show(struct device *dev,
|
||||||
struct device_attribute *attr, char *buf)
|
struct device_attribute *attr, char *buf)
|
||||||
{
|
{
|
||||||
struct memory_block *mem = to_memory_block(dev);
|
struct memory_block *mem = to_memory_block(dev);
|
||||||
|
unsigned long start_pfn = section_nr_to_pfn(mem->start_section_nr);
|
||||||
|
|
||||||
return sysfs_emit(buf, "%d\n", mem->phys_device);
|
return sysfs_emit(buf, "%d\n",
|
||||||
|
arch_get_memory_phys_device(start_pfn));
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_MEMORY_HOTREMOVE
|
#ifdef CONFIG_MEMORY_HOTREMOVE
|
||||||
@@ -488,11 +488,7 @@ static DEVICE_ATTR_WO(soft_offline_page);
|
|||||||
static DEVICE_ATTR_WO(hard_offline_page);
|
static DEVICE_ATTR_WO(hard_offline_page);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/* See phys_device_show(). */
|
||||||
* Note that phys_device is optional. It is here to allow for
|
|
||||||
* differentiation between which *physical* devices each
|
|
||||||
* section belongs to...
|
|
||||||
*/
|
|
||||||
int __weak arch_get_memory_phys_device(unsigned long start_pfn)
|
int __weak arch_get_memory_phys_device(unsigned long start_pfn)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
@@ -574,7 +570,6 @@ int register_memory(struct memory_block *memory)
|
|||||||
static int init_memory_block(unsigned long block_id, unsigned long state)
|
static int init_memory_block(unsigned long block_id, unsigned long state)
|
||||||
{
|
{
|
||||||
struct memory_block *mem;
|
struct memory_block *mem;
|
||||||
unsigned long start_pfn;
|
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
mem = find_memory_block_by_id(block_id);
|
mem = find_memory_block_by_id(block_id);
|
||||||
@@ -588,8 +583,6 @@ static int init_memory_block(unsigned long block_id, unsigned long state)
|
|||||||
|
|
||||||
mem->start_section_nr = block_id * sections_per_block;
|
mem->start_section_nr = block_id * sections_per_block;
|
||||||
mem->state = state;
|
mem->state = state;
|
||||||
start_pfn = section_nr_to_pfn(mem->start_section_nr);
|
|
||||||
mem->phys_device = arch_get_memory_phys_device(start_pfn);
|
|
||||||
mem->nid = NUMA_NO_NODE;
|
mem->nid = NUMA_NO_NODE;
|
||||||
|
|
||||||
ret = register_memory(mem);
|
ret = register_memory(mem);
|
||||||
|
@@ -799,6 +799,9 @@ int software_node_register(const struct software_node *node)
|
|||||||
if (software_node_to_swnode(node))
|
if (software_node_to_swnode(node))
|
||||||
return -EEXIST;
|
return -EEXIST;
|
||||||
|
|
||||||
|
if (node->parent && !parent)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
return PTR_ERR_OR_ZERO(swnode_register(node, parent, 0));
|
return PTR_ERR_OR_ZERO(swnode_register(node, parent, 0));
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(software_node_register);
|
EXPORT_SYMBOL_GPL(software_node_register);
|
||||||
|
@@ -2,3 +2,4 @@
|
|||||||
obj-$(CONFIG_TEST_ASYNC_DRIVER_PROBE) += test_async_driver_probe.o
|
obj-$(CONFIG_TEST_ASYNC_DRIVER_PROBE) += test_async_driver_probe.o
|
||||||
|
|
||||||
obj-$(CONFIG_KUNIT_DRIVER_PE_TEST) += property-entry-test.o
|
obj-$(CONFIG_KUNIT_DRIVER_PE_TEST) += property-entry-test.o
|
||||||
|
CFLAGS_REMOVE_property-entry-test.o += -fplugin-arg-structleak_plugin-byref -fplugin-arg-structleak_plugin-byref-all
|
||||||
|
@@ -871,6 +871,7 @@ static int rsxx_pci_probe(struct pci_dev *dev,
|
|||||||
card->event_wq = create_singlethread_workqueue(DRIVER_NAME"_event");
|
card->event_wq = create_singlethread_workqueue(DRIVER_NAME"_event");
|
||||||
if (!card->event_wq) {
|
if (!card->event_wq) {
|
||||||
dev_err(CARD_TO_DEV(card), "Failed card event setup.\n");
|
dev_err(CARD_TO_DEV(card), "Failed card event setup.\n");
|
||||||
|
st = -ENOMEM;
|
||||||
goto failed_event_handler;
|
goto failed_event_handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -637,7 +637,7 @@ static ssize_t writeback_store(struct device *dev,
|
|||||||
struct bio_vec bio_vec;
|
struct bio_vec bio_vec;
|
||||||
struct page *page;
|
struct page *page;
|
||||||
ssize_t ret = len;
|
ssize_t ret = len;
|
||||||
int mode;
|
int mode, err;
|
||||||
unsigned long blk_idx = 0;
|
unsigned long blk_idx = 0;
|
||||||
|
|
||||||
if (sysfs_streq(buf, "idle"))
|
if (sysfs_streq(buf, "idle"))
|
||||||
@@ -738,12 +738,17 @@ static ssize_t writeback_store(struct device *dev,
|
|||||||
* XXX: A single page IO would be inefficient for write
|
* XXX: A single page IO would be inefficient for write
|
||||||
* but it would be not bad as starter.
|
* but it would be not bad as starter.
|
||||||
*/
|
*/
|
||||||
ret = submit_bio_wait(&bio);
|
err = submit_bio_wait(&bio);
|
||||||
if (ret) {
|
if (err) {
|
||||||
zram_slot_lock(zram, index);
|
zram_slot_lock(zram, index);
|
||||||
zram_clear_flag(zram, index, ZRAM_UNDER_WB);
|
zram_clear_flag(zram, index, ZRAM_UNDER_WB);
|
||||||
zram_clear_flag(zram, index, ZRAM_IDLE);
|
zram_clear_flag(zram, index, ZRAM_IDLE);
|
||||||
zram_slot_unlock(zram, index);
|
zram_slot_unlock(zram, index);
|
||||||
|
/*
|
||||||
|
* Return last IO error unless every IO were
|
||||||
|
* not suceeded.
|
||||||
|
*/
|
||||||
|
ret = err;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -183,7 +183,10 @@ static inline int gdsc_assert_reset(struct gdsc *sc)
|
|||||||
static inline void gdsc_force_mem_on(struct gdsc *sc)
|
static inline void gdsc_force_mem_on(struct gdsc *sc)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
u32 mask = RETAIN_MEM | RETAIN_PERIPH;
|
u32 mask = RETAIN_MEM;
|
||||||
|
|
||||||
|
if (!(sc->flags & NO_RET_PERIPH))
|
||||||
|
mask |= RETAIN_PERIPH;
|
||||||
|
|
||||||
for (i = 0; i < sc->cxc_count; i++)
|
for (i = 0; i < sc->cxc_count; i++)
|
||||||
regmap_update_bits(sc->regmap, sc->cxcs[i], mask, mask);
|
regmap_update_bits(sc->regmap, sc->cxcs[i], mask, mask);
|
||||||
@@ -192,7 +195,10 @@ static inline void gdsc_force_mem_on(struct gdsc *sc)
|
|||||||
static inline void gdsc_clear_mem_on(struct gdsc *sc)
|
static inline void gdsc_clear_mem_on(struct gdsc *sc)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
u32 mask = RETAIN_MEM | RETAIN_PERIPH;
|
u32 mask = RETAIN_MEM;
|
||||||
|
|
||||||
|
if (!(sc->flags & NO_RET_PERIPH))
|
||||||
|
mask |= RETAIN_PERIPH;
|
||||||
|
|
||||||
for (i = 0; i < sc->cxc_count; i++)
|
for (i = 0; i < sc->cxc_count; i++)
|
||||||
regmap_update_bits(sc->regmap, sc->cxcs[i], mask, 0);
|
regmap_update_bits(sc->regmap, sc->cxcs[i], mask, 0);
|
||||||
|
@@ -42,7 +42,7 @@ struct gdsc {
|
|||||||
#define PWRSTS_ON BIT(2)
|
#define PWRSTS_ON BIT(2)
|
||||||
#define PWRSTS_OFF_ON (PWRSTS_OFF | PWRSTS_ON)
|
#define PWRSTS_OFF_ON (PWRSTS_OFF | PWRSTS_ON)
|
||||||
#define PWRSTS_RET_ON (PWRSTS_RET | PWRSTS_ON)
|
#define PWRSTS_RET_ON (PWRSTS_RET | PWRSTS_ON)
|
||||||
const u8 flags;
|
const u16 flags;
|
||||||
#define VOTABLE BIT(0)
|
#define VOTABLE BIT(0)
|
||||||
#define CLAMP_IO BIT(1)
|
#define CLAMP_IO BIT(1)
|
||||||
#define HW_CTRL BIT(2)
|
#define HW_CTRL BIT(2)
|
||||||
@@ -51,6 +51,7 @@ struct gdsc {
|
|||||||
#define POLL_CFG_GDSCR BIT(5)
|
#define POLL_CFG_GDSCR BIT(5)
|
||||||
#define ALWAYS_ON BIT(6)
|
#define ALWAYS_ON BIT(6)
|
||||||
#define RETAIN_FF_ENABLE BIT(7)
|
#define RETAIN_FF_ENABLE BIT(7)
|
||||||
|
#define NO_RET_PERIPH BIT(8)
|
||||||
struct reset_controller_dev *rcdev;
|
struct reset_controller_dev *rcdev;
|
||||||
unsigned int *resets;
|
unsigned int *resets;
|
||||||
unsigned int reset_count;
|
unsigned int reset_count;
|
||||||
|
@@ -253,12 +253,16 @@ static struct gdsc gpu_cx_gdsc = {
|
|||||||
static struct gdsc gpu_gx_gdsc = {
|
static struct gdsc gpu_gx_gdsc = {
|
||||||
.gdscr = 0x1094,
|
.gdscr = 0x1094,
|
||||||
.clamp_io_ctrl = 0x130,
|
.clamp_io_ctrl = 0x130,
|
||||||
|
.resets = (unsigned int []){ GPU_GX_BCR },
|
||||||
|
.reset_count = 1,
|
||||||
|
.cxcs = (unsigned int []){ 0x1098 },
|
||||||
|
.cxc_count = 1,
|
||||||
.pd = {
|
.pd = {
|
||||||
.name = "gpu_gx",
|
.name = "gpu_gx",
|
||||||
},
|
},
|
||||||
.parent = &gpu_cx_gdsc.pd,
|
.parent = &gpu_cx_gdsc.pd,
|
||||||
.pwrsts = PWRSTS_OFF_ON,
|
.pwrsts = PWRSTS_OFF_ON | PWRSTS_RET,
|
||||||
.flags = CLAMP_IO | AON_RESET,
|
.flags = CLAMP_IO | SW_RESET | AON_RESET | NO_RET_PERIPH,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct clk_regmap *gpucc_msm8998_clocks[] = {
|
static struct clk_regmap *gpucc_msm8998_clocks[] = {
|
||||||
|
@@ -317,9 +317,9 @@ static int qcom_cpufreq_hw_cpu_init(struct cpufreq_policy *policy)
|
|||||||
}
|
}
|
||||||
|
|
||||||
base = ioremap(res->start, resource_size(res));
|
base = ioremap(res->start, resource_size(res));
|
||||||
if (IS_ERR(base)) {
|
if (!base) {
|
||||||
dev_err(dev, "failed to map resource %pR\n", res);
|
dev_err(dev, "failed to map resource %pR\n", res);
|
||||||
ret = PTR_ERR(base);
|
ret = -ENOMEM;
|
||||||
goto release_region;
|
goto release_region;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -368,7 +368,7 @@ static int qcom_cpufreq_hw_cpu_init(struct cpufreq_policy *policy)
|
|||||||
error:
|
error:
|
||||||
kfree(data);
|
kfree(data);
|
||||||
unmap_base:
|
unmap_base:
|
||||||
iounmap(data->base);
|
iounmap(base);
|
||||||
release_region:
|
release_region:
|
||||||
release_mem_region(res->start, resource_size(res));
|
release_mem_region(res->start, resource_size(res));
|
||||||
return ret;
|
return ret;
|
||||||
|
@@ -96,6 +96,18 @@ static void install_memreserve_table(void)
|
|||||||
efi_err("Failed to install memreserve config table!\n");
|
efi_err("Failed to install memreserve config table!\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static u32 get_supported_rt_services(void)
|
||||||
|
{
|
||||||
|
const efi_rt_properties_table_t *rt_prop_table;
|
||||||
|
u32 supported = EFI_RT_SUPPORTED_ALL;
|
||||||
|
|
||||||
|
rt_prop_table = get_efi_config_table(EFI_RT_PROPERTIES_TABLE_GUID);
|
||||||
|
if (rt_prop_table)
|
||||||
|
supported &= rt_prop_table->runtime_services_supported;
|
||||||
|
|
||||||
|
return supported;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* EFI entry point for the arm/arm64 EFI stubs. This is the entrypoint
|
* EFI entry point for the arm/arm64 EFI stubs. This is the entrypoint
|
||||||
* that is described in the PE/COFF header. Most of the code is the same
|
* that is described in the PE/COFF header. Most of the code is the same
|
||||||
@@ -250,6 +262,10 @@ efi_status_t __efiapi efi_pe_entry(efi_handle_t handle,
|
|||||||
(prop_tbl->memory_protection_attribute &
|
(prop_tbl->memory_protection_attribute &
|
||||||
EFI_PROPERTIES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA);
|
EFI_PROPERTIES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA);
|
||||||
|
|
||||||
|
/* force efi_novamap if SetVirtualAddressMap() is unsupported */
|
||||||
|
efi_novamap |= !(get_supported_rt_services() &
|
||||||
|
EFI_RT_SUPPORTED_SET_VIRTUAL_ADDRESS_MAP);
|
||||||
|
|
||||||
/* hibernation expects the runtime regions to stay in the same place */
|
/* hibernation expects the runtime regions to stay in the same place */
|
||||||
if (!IS_ENABLED(CONFIG_HIBERNATION) && !efi_nokaslr && !flat_va_mapping) {
|
if (!IS_ENABLED(CONFIG_HIBERNATION) && !efi_nokaslr && !flat_va_mapping) {
|
||||||
/*
|
/*
|
||||||
|
@@ -112,8 +112,29 @@ MODULE_DEVICE_TABLE(i2c, pca953x_id);
|
|||||||
#ifdef CONFIG_GPIO_PCA953X_IRQ
|
#ifdef CONFIG_GPIO_PCA953X_IRQ
|
||||||
|
|
||||||
#include <linux/dmi.h>
|
#include <linux/dmi.h>
|
||||||
#include <linux/gpio.h>
|
|
||||||
#include <linux/list.h>
|
static const struct acpi_gpio_params pca953x_irq_gpios = { 0, 0, true };
|
||||||
|
|
||||||
|
static const struct acpi_gpio_mapping pca953x_acpi_irq_gpios[] = {
|
||||||
|
{ "irq-gpios", &pca953x_irq_gpios, 1, ACPI_GPIO_QUIRK_ABSOLUTE_NUMBER },
|
||||||
|
{ }
|
||||||
|
};
|
||||||
|
|
||||||
|
static int pca953x_acpi_get_irq(struct device *dev)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = devm_acpi_dev_add_driver_gpios(dev, pca953x_acpi_irq_gpios);
|
||||||
|
if (ret)
|
||||||
|
dev_warn(dev, "can't add GPIO ACPI mapping\n");
|
||||||
|
|
||||||
|
ret = acpi_dev_gpio_irq_get_by(ACPI_COMPANION(dev), "irq-gpios", 0);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
dev_info(dev, "ACPI interrupt quirk (IRQ %d)\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static const struct dmi_system_id pca953x_dmi_acpi_irq_info[] = {
|
static const struct dmi_system_id pca953x_dmi_acpi_irq_info[] = {
|
||||||
{
|
{
|
||||||
@@ -132,59 +153,6 @@ static const struct dmi_system_id pca953x_dmi_acpi_irq_info[] = {
|
|||||||
},
|
},
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef CONFIG_ACPI
|
|
||||||
static int pca953x_acpi_get_pin(struct acpi_resource *ares, void *data)
|
|
||||||
{
|
|
||||||
struct acpi_resource_gpio *agpio;
|
|
||||||
int *pin = data;
|
|
||||||
|
|
||||||
if (acpi_gpio_get_irq_resource(ares, &agpio))
|
|
||||||
*pin = agpio->pin_table[0];
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int pca953x_acpi_find_pin(struct device *dev)
|
|
||||||
{
|
|
||||||
struct acpi_device *adev = ACPI_COMPANION(dev);
|
|
||||||
int pin = -ENOENT, ret;
|
|
||||||
LIST_HEAD(r);
|
|
||||||
|
|
||||||
ret = acpi_dev_get_resources(adev, &r, pca953x_acpi_get_pin, &pin);
|
|
||||||
acpi_dev_free_resource_list(&r);
|
|
||||||
if (ret < 0)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
return pin;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
static inline int pca953x_acpi_find_pin(struct device *dev) { return -ENXIO; }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static int pca953x_acpi_get_irq(struct device *dev)
|
|
||||||
{
|
|
||||||
int pin, ret;
|
|
||||||
|
|
||||||
pin = pca953x_acpi_find_pin(dev);
|
|
||||||
if (pin < 0)
|
|
||||||
return pin;
|
|
||||||
|
|
||||||
dev_info(dev, "Applying ACPI interrupt quirk (GPIO %d)\n", pin);
|
|
||||||
|
|
||||||
if (!gpio_is_valid(pin))
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
ret = gpio_request(pin, "pca953x interrupt");
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
ret = gpio_to_irq(pin);
|
|
||||||
|
|
||||||
/* When pin is used as an IRQ, no need to keep it requested */
|
|
||||||
gpio_free(pin);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static const struct acpi_device_id pca953x_acpi_ids[] = {
|
static const struct acpi_device_id pca953x_acpi_ids[] = {
|
||||||
|
@@ -649,6 +649,7 @@ static int acpi_populate_gpio_lookup(struct acpi_resource *ares, void *data)
|
|||||||
if (!lookup->desc) {
|
if (!lookup->desc) {
|
||||||
const struct acpi_resource_gpio *agpio = &ares->data.gpio;
|
const struct acpi_resource_gpio *agpio = &ares->data.gpio;
|
||||||
bool gpioint = agpio->connection_type == ACPI_RESOURCE_GPIO_TYPE_INT;
|
bool gpioint = agpio->connection_type == ACPI_RESOURCE_GPIO_TYPE_INT;
|
||||||
|
struct gpio_desc *desc;
|
||||||
int pin_index;
|
int pin_index;
|
||||||
|
|
||||||
if (lookup->info.quirks & ACPI_GPIO_QUIRK_ONLY_GPIOIO && gpioint)
|
if (lookup->info.quirks & ACPI_GPIO_QUIRK_ONLY_GPIOIO && gpioint)
|
||||||
@@ -661,8 +662,12 @@ static int acpi_populate_gpio_lookup(struct acpi_resource *ares, void *data)
|
|||||||
if (pin_index >= agpio->pin_table_length)
|
if (pin_index >= agpio->pin_table_length)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
lookup->desc = acpi_get_gpiod(agpio->resource_source.string_ptr,
|
if (lookup->info.quirks & ACPI_GPIO_QUIRK_ABSOLUTE_NUMBER)
|
||||||
|
desc = gpio_to_desc(agpio->pin_table[pin_index]);
|
||||||
|
else
|
||||||
|
desc = acpi_get_gpiod(agpio->resource_source.string_ptr,
|
||||||
agpio->pin_table[pin_index]);
|
agpio->pin_table[pin_index]);
|
||||||
|
lookup->desc = desc;
|
||||||
lookup->info.pin_config = agpio->pin_config;
|
lookup->info.pin_config = agpio->pin_config;
|
||||||
lookup->info.gpioint = gpioint;
|
lookup->info.gpioint = gpioint;
|
||||||
|
|
||||||
@@ -911,8 +916,9 @@ struct gpio_desc *acpi_node_get_gpiod(struct fwnode_handle *fwnode,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* acpi_dev_gpio_irq_get() - Find GpioInt and translate it to Linux IRQ number
|
* acpi_dev_gpio_irq_get_by() - Find GpioInt and translate it to Linux IRQ number
|
||||||
* @adev: pointer to a ACPI device to get IRQ from
|
* @adev: pointer to a ACPI device to get IRQ from
|
||||||
|
* @name: optional name of GpioInt resource
|
||||||
* @index: index of GpioInt resource (starting from %0)
|
* @index: index of GpioInt resource (starting from %0)
|
||||||
*
|
*
|
||||||
* If the device has one or more GpioInt resources, this function can be
|
* If the device has one or more GpioInt resources, this function can be
|
||||||
@@ -922,9 +928,12 @@ struct gpio_desc *acpi_node_get_gpiod(struct fwnode_handle *fwnode,
|
|||||||
* The function is idempotent, though each time it runs it will configure GPIO
|
* The function is idempotent, though each time it runs it will configure GPIO
|
||||||
* pin direction according to the flags in GpioInt resource.
|
* pin direction according to the flags in GpioInt resource.
|
||||||
*
|
*
|
||||||
|
* The function takes optional @name parameter. If the resource has a property
|
||||||
|
* name, then only those will be taken into account.
|
||||||
|
*
|
||||||
* Return: Linux IRQ number (> %0) on success, negative errno on failure.
|
* Return: Linux IRQ number (> %0) on success, negative errno on failure.
|
||||||
*/
|
*/
|
||||||
int acpi_dev_gpio_irq_get(struct acpi_device *adev, int index)
|
int acpi_dev_gpio_irq_get_by(struct acpi_device *adev, const char *name, int index)
|
||||||
{
|
{
|
||||||
int idx, i;
|
int idx, i;
|
||||||
unsigned int irq_flags;
|
unsigned int irq_flags;
|
||||||
@@ -934,7 +943,7 @@ int acpi_dev_gpio_irq_get(struct acpi_device *adev, int index)
|
|||||||
struct acpi_gpio_info info;
|
struct acpi_gpio_info info;
|
||||||
struct gpio_desc *desc;
|
struct gpio_desc *desc;
|
||||||
|
|
||||||
desc = acpi_get_gpiod_by_index(adev, NULL, i, &info);
|
desc = acpi_get_gpiod_by_index(adev, name, i, &info);
|
||||||
|
|
||||||
/* Ignore -EPROBE_DEFER, it only matters if idx matches */
|
/* Ignore -EPROBE_DEFER, it only matters if idx matches */
|
||||||
if (IS_ERR(desc) && PTR_ERR(desc) != -EPROBE_DEFER)
|
if (IS_ERR(desc) && PTR_ERR(desc) != -EPROBE_DEFER)
|
||||||
@@ -971,7 +980,7 @@ int acpi_dev_gpio_irq_get(struct acpi_device *adev, int index)
|
|||||||
}
|
}
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(acpi_dev_gpio_irq_get);
|
EXPORT_SYMBOL_GPL(acpi_dev_gpio_irq_get_by);
|
||||||
|
|
||||||
static acpi_status
|
static acpi_status
|
||||||
acpi_gpio_adr_space_handler(u32 function, acpi_physical_address address,
|
acpi_gpio_adr_space_handler(u32 function, acpi_physical_address address,
|
||||||
|
@@ -474,8 +474,12 @@ EXPORT_SYMBOL_GPL(gpiochip_line_is_valid);
|
|||||||
static void gpiodevice_release(struct device *dev)
|
static void gpiodevice_release(struct device *dev)
|
||||||
{
|
{
|
||||||
struct gpio_device *gdev = dev_get_drvdata(dev);
|
struct gpio_device *gdev = dev_get_drvdata(dev);
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&gpio_lock, flags);
|
||||||
list_del(&gdev->list);
|
list_del(&gdev->list);
|
||||||
|
spin_unlock_irqrestore(&gpio_lock, flags);
|
||||||
|
|
||||||
ida_free(&gpio_ida, gdev->id);
|
ida_free(&gpio_ida, gdev->id);
|
||||||
kfree_const(gdev->label);
|
kfree_const(gdev->label);
|
||||||
kfree(gdev->descs);
|
kfree(gdev->descs);
|
||||||
|
@@ -178,6 +178,7 @@ extern uint amdgpu_smu_memory_pool_size;
|
|||||||
extern uint amdgpu_dc_feature_mask;
|
extern uint amdgpu_dc_feature_mask;
|
||||||
extern uint amdgpu_dc_debug_mask;
|
extern uint amdgpu_dc_debug_mask;
|
||||||
extern uint amdgpu_dm_abm_level;
|
extern uint amdgpu_dm_abm_level;
|
||||||
|
extern int amdgpu_backlight;
|
||||||
extern struct amdgpu_mgpu_info mgpu_info;
|
extern struct amdgpu_mgpu_info mgpu_info;
|
||||||
extern int amdgpu_ras_enable;
|
extern int amdgpu_ras_enable;
|
||||||
extern uint amdgpu_ras_mask;
|
extern uint amdgpu_ras_mask;
|
||||||
|
@@ -768,6 +768,10 @@ uint amdgpu_dm_abm_level = 0;
|
|||||||
MODULE_PARM_DESC(abmlevel, "ABM level (0 = off (default), 1-4 = backlight reduction level) ");
|
MODULE_PARM_DESC(abmlevel, "ABM level (0 = off (default), 1-4 = backlight reduction level) ");
|
||||||
module_param_named(abmlevel, amdgpu_dm_abm_level, uint, 0444);
|
module_param_named(abmlevel, amdgpu_dm_abm_level, uint, 0444);
|
||||||
|
|
||||||
|
int amdgpu_backlight = -1;
|
||||||
|
MODULE_PARM_DESC(backlight, "Backlight control (0 = pwm, 1 = aux, -1 auto (default))");
|
||||||
|
module_param_named(backlight, amdgpu_backlight, bint, 0444);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* DOC: tmz (int)
|
* DOC: tmz (int)
|
||||||
* Trusted Memory Zone (TMZ) is a method to protect data being written
|
* Trusted Memory Zone (TMZ) is a method to protect data being written
|
||||||
|
@@ -2140,6 +2140,11 @@ static void update_connector_ext_caps(struct amdgpu_dm_connector *aconnector)
|
|||||||
caps->ext_caps->bits.hdr_aux_backlight_control == 1)
|
caps->ext_caps->bits.hdr_aux_backlight_control == 1)
|
||||||
caps->aux_support = true;
|
caps->aux_support = true;
|
||||||
|
|
||||||
|
if (amdgpu_backlight == 0)
|
||||||
|
caps->aux_support = false;
|
||||||
|
else if (amdgpu_backlight == 1)
|
||||||
|
caps->aux_support = true;
|
||||||
|
|
||||||
/* From the specification (CTA-861-G), for calculating the maximum
|
/* From the specification (CTA-861-G), for calculating the maximum
|
||||||
* luminance we need to use:
|
* luminance we need to use:
|
||||||
* Luminance = 50*2**(CV/32)
|
* Luminance = 50*2**(CV/32)
|
||||||
@@ -3038,19 +3043,6 @@ static void amdgpu_dm_update_backlight_caps(struct amdgpu_display_manager *dm)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static int set_backlight_via_aux(struct dc_link *link, uint32_t brightness)
|
|
||||||
{
|
|
||||||
bool rc;
|
|
||||||
|
|
||||||
if (!link)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
rc = dc_link_set_backlight_level_nits(link, true, brightness,
|
|
||||||
AUX_BL_DEFAULT_TRANSITION_TIME_MS);
|
|
||||||
|
|
||||||
return rc ? 0 : 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int get_brightness_range(const struct amdgpu_dm_backlight_caps *caps,
|
static int get_brightness_range(const struct amdgpu_dm_backlight_caps *caps,
|
||||||
unsigned *min, unsigned *max)
|
unsigned *min, unsigned *max)
|
||||||
{
|
{
|
||||||
@@ -3113,9 +3105,10 @@ static int amdgpu_dm_backlight_update_status(struct backlight_device *bd)
|
|||||||
brightness = convert_brightness_from_user(&caps, bd->props.brightness);
|
brightness = convert_brightness_from_user(&caps, bd->props.brightness);
|
||||||
// Change brightness based on AUX property
|
// Change brightness based on AUX property
|
||||||
if (caps.aux_support)
|
if (caps.aux_support)
|
||||||
return set_backlight_via_aux(link, brightness);
|
rc = dc_link_set_backlight_level_nits(link, true, brightness,
|
||||||
|
AUX_BL_DEFAULT_TRANSITION_TIME_MS);
|
||||||
rc = dc_link_set_backlight_level(dm->backlight_link, brightness, 0);
|
else
|
||||||
|
rc = dc_link_set_backlight_level(dm->backlight_link, brightness, 0);
|
||||||
|
|
||||||
return rc ? 0 : 1;
|
return rc ? 0 : 1;
|
||||||
}
|
}
|
||||||
@@ -3123,11 +3116,27 @@ static int amdgpu_dm_backlight_update_status(struct backlight_device *bd)
|
|||||||
static int amdgpu_dm_backlight_get_brightness(struct backlight_device *bd)
|
static int amdgpu_dm_backlight_get_brightness(struct backlight_device *bd)
|
||||||
{
|
{
|
||||||
struct amdgpu_display_manager *dm = bl_get_data(bd);
|
struct amdgpu_display_manager *dm = bl_get_data(bd);
|
||||||
int ret = dc_link_get_backlight_level(dm->backlight_link);
|
struct amdgpu_dm_backlight_caps caps;
|
||||||
|
|
||||||
if (ret == DC_ERROR_UNEXPECTED)
|
amdgpu_dm_update_backlight_caps(dm);
|
||||||
return bd->props.brightness;
|
caps = dm->backlight_caps;
|
||||||
return convert_brightness_to_user(&dm->backlight_caps, ret);
|
|
||||||
|
if (caps.aux_support) {
|
||||||
|
struct dc_link *link = (struct dc_link *)dm->backlight_link;
|
||||||
|
u32 avg, peak;
|
||||||
|
bool rc;
|
||||||
|
|
||||||
|
rc = dc_link_get_backlight_level_nits(link, &avg, &peak);
|
||||||
|
if (!rc)
|
||||||
|
return bd->props.brightness;
|
||||||
|
return convert_brightness_to_user(&caps, avg);
|
||||||
|
} else {
|
||||||
|
int ret = dc_link_get_backlight_level(dm->backlight_link);
|
||||||
|
|
||||||
|
if (ret == DC_ERROR_UNEXPECTED)
|
||||||
|
return bd->props.brightness;
|
||||||
|
return convert_brightness_to_user(&caps, ret);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct backlight_ops amdgpu_dm_backlight_ops = {
|
static const struct backlight_ops amdgpu_dm_backlight_ops = {
|
||||||
|
@@ -2555,7 +2555,6 @@ bool dc_link_set_backlight_level(const struct dc_link *link,
|
|||||||
if (pipe_ctx->plane_state == NULL)
|
if (pipe_ctx->plane_state == NULL)
|
||||||
frame_ramp = 0;
|
frame_ramp = 0;
|
||||||
} else {
|
} else {
|
||||||
ASSERT(false);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1058,8 +1058,6 @@ static void patch_bounding_box(struct dc *dc, struct _vcs_dpi_soc_bounding_box_s
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
DC_FP_START();
|
|
||||||
|
|
||||||
if (dc->bb_overrides.sr_exit_time_ns) {
|
if (dc->bb_overrides.sr_exit_time_ns) {
|
||||||
for (i = 0; i < WM_SET_COUNT; i++) {
|
for (i = 0; i < WM_SET_COUNT; i++) {
|
||||||
dc->clk_mgr->bw_params->wm_table.entries[i].sr_exit_time_us =
|
dc->clk_mgr->bw_params->wm_table.entries[i].sr_exit_time_us =
|
||||||
@@ -1084,8 +1082,6 @@ static void patch_bounding_box(struct dc *dc, struct _vcs_dpi_soc_bounding_box_s
|
|||||||
dc->bb_overrides.dram_clock_change_latency_ns / 1000.0;
|
dc->bb_overrides.dram_clock_change_latency_ns / 1000.0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DC_FP_END();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void dcn21_calculate_wm(
|
void dcn21_calculate_wm(
|
||||||
@@ -1183,7 +1179,7 @@ static noinline bool dcn21_validate_bandwidth_fp(struct dc *dc,
|
|||||||
int vlevel = 0;
|
int vlevel = 0;
|
||||||
int pipe_split_from[MAX_PIPES];
|
int pipe_split_from[MAX_PIPES];
|
||||||
int pipe_cnt = 0;
|
int pipe_cnt = 0;
|
||||||
display_e2e_pipe_params_st *pipes = kzalloc(dc->res_pool->pipe_count * sizeof(display_e2e_pipe_params_st), GFP_KERNEL);
|
display_e2e_pipe_params_st *pipes = kzalloc(dc->res_pool->pipe_count * sizeof(display_e2e_pipe_params_st), GFP_ATOMIC);
|
||||||
DC_LOGGER_INIT(dc->ctx->logger);
|
DC_LOGGER_INIT(dc->ctx->logger);
|
||||||
|
|
||||||
BW_VAL_TRACE_COUNT();
|
BW_VAL_TRACE_COUNT();
|
||||||
|
@@ -1506,6 +1506,48 @@ static int vega10_populate_single_lclk_level(struct pp_hwmgr *hwmgr,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int vega10_override_pcie_parameters(struct pp_hwmgr *hwmgr)
|
||||||
|
{
|
||||||
|
struct amdgpu_device *adev = (struct amdgpu_device *)(hwmgr->adev);
|
||||||
|
struct vega10_hwmgr *data =
|
||||||
|
(struct vega10_hwmgr *)(hwmgr->backend);
|
||||||
|
uint32_t pcie_gen = 0, pcie_width = 0;
|
||||||
|
PPTable_t *pp_table = &(data->smc_state_table.pp_table);
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN4)
|
||||||
|
pcie_gen = 3;
|
||||||
|
else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3)
|
||||||
|
pcie_gen = 2;
|
||||||
|
else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2)
|
||||||
|
pcie_gen = 1;
|
||||||
|
else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN1)
|
||||||
|
pcie_gen = 0;
|
||||||
|
|
||||||
|
if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X16)
|
||||||
|
pcie_width = 6;
|
||||||
|
else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X12)
|
||||||
|
pcie_width = 5;
|
||||||
|
else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X8)
|
||||||
|
pcie_width = 4;
|
||||||
|
else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X4)
|
||||||
|
pcie_width = 3;
|
||||||
|
else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X2)
|
||||||
|
pcie_width = 2;
|
||||||
|
else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X1)
|
||||||
|
pcie_width = 1;
|
||||||
|
|
||||||
|
for (i = 0; i < NUM_LINK_LEVELS; i++) {
|
||||||
|
if (pp_table->PcieGenSpeed[i] > pcie_gen)
|
||||||
|
pp_table->PcieGenSpeed[i] = pcie_gen;
|
||||||
|
|
||||||
|
if (pp_table->PcieLaneCount[i] > pcie_width)
|
||||||
|
pp_table->PcieLaneCount[i] = pcie_width;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int vega10_populate_smc_link_levels(struct pp_hwmgr *hwmgr)
|
static int vega10_populate_smc_link_levels(struct pp_hwmgr *hwmgr)
|
||||||
{
|
{
|
||||||
int result = -1;
|
int result = -1;
|
||||||
@@ -2557,6 +2599,11 @@ static int vega10_init_smc_table(struct pp_hwmgr *hwmgr)
|
|||||||
"Failed to initialize Link Level!",
|
"Failed to initialize Link Level!",
|
||||||
return result);
|
return result);
|
||||||
|
|
||||||
|
result = vega10_override_pcie_parameters(hwmgr);
|
||||||
|
PP_ASSERT_WITH_CODE(!result,
|
||||||
|
"Failed to override pcie parameters!",
|
||||||
|
return result);
|
||||||
|
|
||||||
result = vega10_populate_all_graphic_levels(hwmgr);
|
result = vega10_populate_all_graphic_levels(hwmgr);
|
||||||
PP_ASSERT_WITH_CODE(!result,
|
PP_ASSERT_WITH_CODE(!result,
|
||||||
"Failed to initialize Graphics Level!",
|
"Failed to initialize Graphics Level!",
|
||||||
@@ -2923,6 +2970,7 @@ static int vega10_start_dpm(struct pp_hwmgr *hwmgr, uint32_t bitmap)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int vega10_enable_disable_PCC_limit_feature(struct pp_hwmgr *hwmgr, bool enable)
|
static int vega10_enable_disable_PCC_limit_feature(struct pp_hwmgr *hwmgr, bool enable)
|
||||||
{
|
{
|
||||||
struct vega10_hwmgr *data = hwmgr->backend;
|
struct vega10_hwmgr *data = hwmgr->backend;
|
||||||
|
@@ -481,6 +481,67 @@ static void vega12_init_dpm_state(struct vega12_dpm_state *dpm_state)
|
|||||||
dpm_state->hard_max_level = 0xffff;
|
dpm_state->hard_max_level = 0xffff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int vega12_override_pcie_parameters(struct pp_hwmgr *hwmgr)
|
||||||
|
{
|
||||||
|
struct amdgpu_device *adev = (struct amdgpu_device *)(hwmgr->adev);
|
||||||
|
struct vega12_hwmgr *data =
|
||||||
|
(struct vega12_hwmgr *)(hwmgr->backend);
|
||||||
|
uint32_t pcie_gen = 0, pcie_width = 0, smu_pcie_arg, pcie_gen_arg, pcie_width_arg;
|
||||||
|
PPTable_t *pp_table = &(data->smc_state_table.pp_table);
|
||||||
|
int i;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN4)
|
||||||
|
pcie_gen = 3;
|
||||||
|
else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3)
|
||||||
|
pcie_gen = 2;
|
||||||
|
else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2)
|
||||||
|
pcie_gen = 1;
|
||||||
|
else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN1)
|
||||||
|
pcie_gen = 0;
|
||||||
|
|
||||||
|
if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X16)
|
||||||
|
pcie_width = 6;
|
||||||
|
else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X12)
|
||||||
|
pcie_width = 5;
|
||||||
|
else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X8)
|
||||||
|
pcie_width = 4;
|
||||||
|
else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X4)
|
||||||
|
pcie_width = 3;
|
||||||
|
else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X2)
|
||||||
|
pcie_width = 2;
|
||||||
|
else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X1)
|
||||||
|
pcie_width = 1;
|
||||||
|
|
||||||
|
/* Bit 31:16: LCLK DPM level. 0 is DPM0, and 1 is DPM1
|
||||||
|
* Bit 15:8: PCIE GEN, 0 to 3 corresponds to GEN1 to GEN4
|
||||||
|
* Bit 7:0: PCIE lane width, 1 to 7 corresponds is x1 to x32
|
||||||
|
*/
|
||||||
|
for (i = 0; i < NUM_LINK_LEVELS; i++) {
|
||||||
|
pcie_gen_arg = (pp_table->PcieGenSpeed[i] > pcie_gen) ? pcie_gen :
|
||||||
|
pp_table->PcieGenSpeed[i];
|
||||||
|
pcie_width_arg = (pp_table->PcieLaneCount[i] > pcie_width) ? pcie_width :
|
||||||
|
pp_table->PcieLaneCount[i];
|
||||||
|
|
||||||
|
if (pcie_gen_arg != pp_table->PcieGenSpeed[i] || pcie_width_arg !=
|
||||||
|
pp_table->PcieLaneCount[i]) {
|
||||||
|
smu_pcie_arg = (i << 16) | (pcie_gen_arg << 8) | pcie_width_arg;
|
||||||
|
ret = smum_send_msg_to_smc_with_parameter(hwmgr,
|
||||||
|
PPSMC_MSG_OverridePcieParameters, smu_pcie_arg,
|
||||||
|
NULL);
|
||||||
|
PP_ASSERT_WITH_CODE(!ret,
|
||||||
|
"[OverridePcieParameters] Attempt to override pcie params failed!",
|
||||||
|
return ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* update the pptable */
|
||||||
|
pp_table->PcieGenSpeed[i] = pcie_gen_arg;
|
||||||
|
pp_table->PcieLaneCount[i] = pcie_width_arg;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int vega12_get_number_of_dpm_level(struct pp_hwmgr *hwmgr,
|
static int vega12_get_number_of_dpm_level(struct pp_hwmgr *hwmgr,
|
||||||
PPCLK_e clk_id, uint32_t *num_of_levels)
|
PPCLK_e clk_id, uint32_t *num_of_levels)
|
||||||
{
|
{
|
||||||
@@ -969,6 +1030,11 @@ static int vega12_enable_dpm_tasks(struct pp_hwmgr *hwmgr)
|
|||||||
"Failed to enable all smu features!",
|
"Failed to enable all smu features!",
|
||||||
return result);
|
return result);
|
||||||
|
|
||||||
|
result = vega12_override_pcie_parameters(hwmgr);
|
||||||
|
PP_ASSERT_WITH_CODE(!result,
|
||||||
|
"[EnableDPMTasks] Failed to override pcie parameters!",
|
||||||
|
return result);
|
||||||
|
|
||||||
tmp_result = vega12_power_control_set_level(hwmgr);
|
tmp_result = vega12_power_control_set_level(hwmgr);
|
||||||
PP_ASSERT_WITH_CODE(!tmp_result,
|
PP_ASSERT_WITH_CODE(!tmp_result,
|
||||||
"Failed to power control set level!",
|
"Failed to power control set level!",
|
||||||
|
@@ -832,7 +832,9 @@ static int vega20_override_pcie_parameters(struct pp_hwmgr *hwmgr)
|
|||||||
struct amdgpu_device *adev = (struct amdgpu_device *)(hwmgr->adev);
|
struct amdgpu_device *adev = (struct amdgpu_device *)(hwmgr->adev);
|
||||||
struct vega20_hwmgr *data =
|
struct vega20_hwmgr *data =
|
||||||
(struct vega20_hwmgr *)(hwmgr->backend);
|
(struct vega20_hwmgr *)(hwmgr->backend);
|
||||||
uint32_t pcie_gen = 0, pcie_width = 0, smu_pcie_arg;
|
uint32_t pcie_gen = 0, pcie_width = 0, smu_pcie_arg, pcie_gen_arg, pcie_width_arg;
|
||||||
|
PPTable_t *pp_table = &(data->smc_state_table.pp_table);
|
||||||
|
int i;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN4)
|
if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN4)
|
||||||
@@ -861,17 +863,27 @@ static int vega20_override_pcie_parameters(struct pp_hwmgr *hwmgr)
|
|||||||
* Bit 15:8: PCIE GEN, 0 to 3 corresponds to GEN1 to GEN4
|
* Bit 15:8: PCIE GEN, 0 to 3 corresponds to GEN1 to GEN4
|
||||||
* Bit 7:0: PCIE lane width, 1 to 7 corresponds is x1 to x32
|
* Bit 7:0: PCIE lane width, 1 to 7 corresponds is x1 to x32
|
||||||
*/
|
*/
|
||||||
smu_pcie_arg = (1 << 16) | (pcie_gen << 8) | pcie_width;
|
for (i = 0; i < NUM_LINK_LEVELS; i++) {
|
||||||
ret = smum_send_msg_to_smc_with_parameter(hwmgr,
|
pcie_gen_arg = (pp_table->PcieGenSpeed[i] > pcie_gen) ? pcie_gen :
|
||||||
PPSMC_MSG_OverridePcieParameters, smu_pcie_arg,
|
pp_table->PcieGenSpeed[i];
|
||||||
NULL);
|
pcie_width_arg = (pp_table->PcieLaneCount[i] > pcie_width) ? pcie_width :
|
||||||
PP_ASSERT_WITH_CODE(!ret,
|
pp_table->PcieLaneCount[i];
|
||||||
"[OverridePcieParameters] Attempt to override pcie params failed!",
|
|
||||||
return ret);
|
|
||||||
|
|
||||||
data->pcie_parameters_override = true;
|
if (pcie_gen_arg != pp_table->PcieGenSpeed[i] || pcie_width_arg !=
|
||||||
data->pcie_gen_level1 = pcie_gen;
|
pp_table->PcieLaneCount[i]) {
|
||||||
data->pcie_width_level1 = pcie_width;
|
smu_pcie_arg = (i << 16) | (pcie_gen_arg << 8) | pcie_width_arg;
|
||||||
|
ret = smum_send_msg_to_smc_with_parameter(hwmgr,
|
||||||
|
PPSMC_MSG_OverridePcieParameters, smu_pcie_arg,
|
||||||
|
NULL);
|
||||||
|
PP_ASSERT_WITH_CODE(!ret,
|
||||||
|
"[OverridePcieParameters] Attempt to override pcie params failed!",
|
||||||
|
return ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* update the pptable */
|
||||||
|
pp_table->PcieGenSpeed[i] = pcie_gen_arg;
|
||||||
|
pp_table->PcieLaneCount[i] = pcie_width_arg;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -3320,9 +3332,7 @@ static int vega20_print_clock_levels(struct pp_hwmgr *hwmgr,
|
|||||||
data->od8_settings.od8_settings_array;
|
data->od8_settings.od8_settings_array;
|
||||||
OverDriveTable_t *od_table =
|
OverDriveTable_t *od_table =
|
||||||
&(data->smc_state_table.overdrive_table);
|
&(data->smc_state_table.overdrive_table);
|
||||||
struct phm_ppt_v3_information *pptable_information =
|
PPTable_t *pptable = &(data->smc_state_table.pp_table);
|
||||||
(struct phm_ppt_v3_information *)hwmgr->pptable;
|
|
||||||
PPTable_t *pptable = (PPTable_t *)pptable_information->smc_pptable;
|
|
||||||
struct pp_clock_levels_with_latency clocks;
|
struct pp_clock_levels_with_latency clocks;
|
||||||
struct vega20_single_dpm_table *fclk_dpm_table =
|
struct vega20_single_dpm_table *fclk_dpm_table =
|
||||||
&(data->dpm_table.fclk_table);
|
&(data->dpm_table.fclk_table);
|
||||||
@@ -3421,13 +3431,9 @@ static int vega20_print_clock_levels(struct pp_hwmgr *hwmgr,
|
|||||||
current_lane_width =
|
current_lane_width =
|
||||||
vega20_get_current_pcie_link_width_level(hwmgr);
|
vega20_get_current_pcie_link_width_level(hwmgr);
|
||||||
for (i = 0; i < NUM_LINK_LEVELS; i++) {
|
for (i = 0; i < NUM_LINK_LEVELS; i++) {
|
||||||
if (i == 1 && data->pcie_parameters_override) {
|
gen_speed = pptable->PcieGenSpeed[i];
|
||||||
gen_speed = data->pcie_gen_level1;
|
lane_width = pptable->PcieLaneCount[i];
|
||||||
lane_width = data->pcie_width_level1;
|
|
||||||
} else {
|
|
||||||
gen_speed = pptable->PcieGenSpeed[i];
|
|
||||||
lane_width = pptable->PcieLaneCount[i];
|
|
||||||
}
|
|
||||||
size += sprintf(buf + size, "%d: %s %s %dMhz %s\n", i,
|
size += sprintf(buf + size, "%d: %s %s %dMhz %s\n", i,
|
||||||
(gen_speed == 0) ? "2.5GT/s," :
|
(gen_speed == 0) ? "2.5GT/s," :
|
||||||
(gen_speed == 1) ? "5.0GT/s," :
|
(gen_speed == 1) ? "5.0GT/s," :
|
||||||
|
@@ -340,13 +340,14 @@ static void drm_gem_shmem_vunmap_locked(struct drm_gem_shmem_object *shmem)
|
|||||||
if (--shmem->vmap_use_count > 0)
|
if (--shmem->vmap_use_count > 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (obj->import_attach)
|
if (obj->import_attach) {
|
||||||
dma_buf_vunmap(obj->import_attach->dmabuf, shmem->vaddr);
|
dma_buf_vunmap(obj->import_attach->dmabuf, shmem->vaddr);
|
||||||
else
|
} else {
|
||||||
vunmap(shmem->vaddr);
|
vunmap(shmem->vaddr);
|
||||||
|
drm_gem_shmem_put_pages(shmem);
|
||||||
|
}
|
||||||
|
|
||||||
shmem->vaddr = NULL;
|
shmem->vaddr = NULL;
|
||||||
drm_gem_shmem_put_pages(shmem);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -534,14 +535,28 @@ static vm_fault_t drm_gem_shmem_fault(struct vm_fault *vmf)
|
|||||||
struct drm_gem_object *obj = vma->vm_private_data;
|
struct drm_gem_object *obj = vma->vm_private_data;
|
||||||
struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
|
struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
|
||||||
loff_t num_pages = obj->size >> PAGE_SHIFT;
|
loff_t num_pages = obj->size >> PAGE_SHIFT;
|
||||||
|
vm_fault_t ret;
|
||||||
struct page *page;
|
struct page *page;
|
||||||
|
pgoff_t page_offset;
|
||||||
|
|
||||||
if (vmf->pgoff >= num_pages || WARN_ON_ONCE(!shmem->pages))
|
/* We don't use vmf->pgoff since that has the fake offset */
|
||||||
return VM_FAULT_SIGBUS;
|
page_offset = (vmf->address - vma->vm_start) >> PAGE_SHIFT;
|
||||||
|
|
||||||
page = shmem->pages[vmf->pgoff];
|
mutex_lock(&shmem->pages_lock);
|
||||||
|
|
||||||
return vmf_insert_page(vma, vmf->address, page);
|
if (page_offset >= num_pages ||
|
||||||
|
WARN_ON_ONCE(!shmem->pages) ||
|
||||||
|
shmem->madv < 0) {
|
||||||
|
ret = VM_FAULT_SIGBUS;
|
||||||
|
} else {
|
||||||
|
page = shmem->pages[page_offset];
|
||||||
|
|
||||||
|
ret = vmf_insert_page(vma, vmf->address, page);
|
||||||
|
}
|
||||||
|
|
||||||
|
mutex_unlock(&shmem->pages_lock);
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void drm_gem_shmem_vm_open(struct vm_area_struct *vma)
|
static void drm_gem_shmem_vm_open(struct vm_area_struct *vma)
|
||||||
@@ -590,9 +605,6 @@ int drm_gem_shmem_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma)
|
|||||||
struct drm_gem_shmem_object *shmem;
|
struct drm_gem_shmem_object *shmem;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
/* Remove the fake offset */
|
|
||||||
vma->vm_pgoff -= drm_vma_node_start(&obj->vma_node);
|
|
||||||
|
|
||||||
if (obj->import_attach) {
|
if (obj->import_attach) {
|
||||||
/* Drop the reference drm_gem_mmap_obj() acquired.*/
|
/* Drop the reference drm_gem_mmap_obj() acquired.*/
|
||||||
drm_gem_object_put(obj);
|
drm_gem_object_put(obj);
|
||||||
|
@@ -99,6 +99,8 @@ static int compat_drm_version(struct file *file, unsigned int cmd,
|
|||||||
if (copy_from_user(&v32, (void __user *)arg, sizeof(v32)))
|
if (copy_from_user(&v32, (void __user *)arg, sizeof(v32)))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
|
memset(&v, 0, sizeof(v));
|
||||||
|
|
||||||
v = (struct drm_version) {
|
v = (struct drm_version) {
|
||||||
.name_len = v32.name_len,
|
.name_len = v32.name_len,
|
||||||
.name = compat_ptr(v32.name),
|
.name = compat_ptr(v32.name),
|
||||||
@@ -137,6 +139,9 @@ static int compat_drm_getunique(struct file *file, unsigned int cmd,
|
|||||||
|
|
||||||
if (copy_from_user(&uq32, (void __user *)arg, sizeof(uq32)))
|
if (copy_from_user(&uq32, (void __user *)arg, sizeof(uq32)))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
|
memset(&uq, 0, sizeof(uq));
|
||||||
|
|
||||||
uq = (struct drm_unique){
|
uq = (struct drm_unique){
|
||||||
.unique_len = uq32.unique_len,
|
.unique_len = uq32.unique_len,
|
||||||
.unique = compat_ptr(uq32.unique),
|
.unique = compat_ptr(uq32.unique),
|
||||||
@@ -265,6 +270,8 @@ static int compat_drm_getclient(struct file *file, unsigned int cmd,
|
|||||||
if (copy_from_user(&c32, argp, sizeof(c32)))
|
if (copy_from_user(&c32, argp, sizeof(c32)))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
|
memset(&client, 0, sizeof(client));
|
||||||
|
|
||||||
client.idx = c32.idx;
|
client.idx = c32.idx;
|
||||||
|
|
||||||
err = drm_ioctl_kernel(file, drm_getclient, &client, 0);
|
err = drm_ioctl_kernel(file, drm_getclient, &client, 0);
|
||||||
@@ -852,6 +859,8 @@ static int compat_drm_wait_vblank(struct file *file, unsigned int cmd,
|
|||||||
if (copy_from_user(&req32, argp, sizeof(req32)))
|
if (copy_from_user(&req32, argp, sizeof(req32)))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
|
memset(&req, 0, sizeof(req));
|
||||||
|
|
||||||
req.request.type = req32.request.type;
|
req.request.type = req32.request.type;
|
||||||
req.request.sequence = req32.request.sequence;
|
req.request.sequence = req32.request.sequence;
|
||||||
req.request.signal = req32.request.signal;
|
req.request.signal = req32.request.signal;
|
||||||
@@ -889,6 +898,8 @@ static int compat_drm_mode_addfb2(struct file *file, unsigned int cmd,
|
|||||||
struct drm_mode_fb_cmd2 req64;
|
struct drm_mode_fb_cmd2 req64;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
memset(&req64, 0, sizeof(req64));
|
||||||
|
|
||||||
if (copy_from_user(&req64, argp,
|
if (copy_from_user(&req64, argp,
|
||||||
offsetof(drm_mode_fb_cmd232_t, modifier)))
|
offsetof(drm_mode_fb_cmd232_t, modifier)))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
@@ -708,9 +708,12 @@ static int engine_setup_common(struct intel_engine_cs *engine)
|
|||||||
goto err_status;
|
goto err_status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
err = intel_engine_init_cmd_parser(engine);
|
||||||
|
if (err)
|
||||||
|
goto err_cmd_parser;
|
||||||
|
|
||||||
intel_engine_init_active(engine, ENGINE_PHYSICAL);
|
intel_engine_init_active(engine, ENGINE_PHYSICAL);
|
||||||
intel_engine_init_execlists(engine);
|
intel_engine_init_execlists(engine);
|
||||||
intel_engine_init_cmd_parser(engine);
|
|
||||||
intel_engine_init__pm(engine);
|
intel_engine_init__pm(engine);
|
||||||
intel_engine_init_retire(engine);
|
intel_engine_init_retire(engine);
|
||||||
|
|
||||||
@@ -724,6 +727,8 @@ static int engine_setup_common(struct intel_engine_cs *engine)
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
err_cmd_parser:
|
||||||
|
intel_breadcrumbs_free(engine->breadcrumbs);
|
||||||
err_status:
|
err_status:
|
||||||
cleanup_status_page(engine);
|
cleanup_status_page(engine);
|
||||||
return err;
|
return err;
|
||||||
|
@@ -939,7 +939,7 @@ static void fini_hash_table(struct intel_engine_cs *engine)
|
|||||||
* struct intel_engine_cs based on whether the platform requires software
|
* struct intel_engine_cs based on whether the platform requires software
|
||||||
* command parsing.
|
* command parsing.
|
||||||
*/
|
*/
|
||||||
void intel_engine_init_cmd_parser(struct intel_engine_cs *engine)
|
int intel_engine_init_cmd_parser(struct intel_engine_cs *engine)
|
||||||
{
|
{
|
||||||
const struct drm_i915_cmd_table *cmd_tables;
|
const struct drm_i915_cmd_table *cmd_tables;
|
||||||
int cmd_table_count;
|
int cmd_table_count;
|
||||||
@@ -947,7 +947,7 @@ void intel_engine_init_cmd_parser(struct intel_engine_cs *engine)
|
|||||||
|
|
||||||
if (!IS_GEN(engine->i915, 7) && !(IS_GEN(engine->i915, 9) &&
|
if (!IS_GEN(engine->i915, 7) && !(IS_GEN(engine->i915, 9) &&
|
||||||
engine->class == COPY_ENGINE_CLASS))
|
engine->class == COPY_ENGINE_CLASS))
|
||||||
return;
|
return 0;
|
||||||
|
|
||||||
switch (engine->class) {
|
switch (engine->class) {
|
||||||
case RENDER_CLASS:
|
case RENDER_CLASS:
|
||||||
@@ -1012,19 +1012,19 @@ void intel_engine_init_cmd_parser(struct intel_engine_cs *engine)
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
MISSING_CASE(engine->class);
|
MISSING_CASE(engine->class);
|
||||||
return;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!validate_cmds_sorted(engine, cmd_tables, cmd_table_count)) {
|
if (!validate_cmds_sorted(engine, cmd_tables, cmd_table_count)) {
|
||||||
drm_err(&engine->i915->drm,
|
drm_err(&engine->i915->drm,
|
||||||
"%s: command descriptions are not sorted\n",
|
"%s: command descriptions are not sorted\n",
|
||||||
engine->name);
|
engine->name);
|
||||||
return;
|
goto out;
|
||||||
}
|
}
|
||||||
if (!validate_regs_sorted(engine)) {
|
if (!validate_regs_sorted(engine)) {
|
||||||
drm_err(&engine->i915->drm,
|
drm_err(&engine->i915->drm,
|
||||||
"%s: registers are not sorted\n", engine->name);
|
"%s: registers are not sorted\n", engine->name);
|
||||||
return;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = init_hash_table(engine, cmd_tables, cmd_table_count);
|
ret = init_hash_table(engine, cmd_tables, cmd_table_count);
|
||||||
@@ -1032,10 +1032,17 @@ void intel_engine_init_cmd_parser(struct intel_engine_cs *engine)
|
|||||||
drm_err(&engine->i915->drm,
|
drm_err(&engine->i915->drm,
|
||||||
"%s: initialised failed!\n", engine->name);
|
"%s: initialised failed!\n", engine->name);
|
||||||
fini_hash_table(engine);
|
fini_hash_table(engine);
|
||||||
return;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
engine->flags |= I915_ENGINE_USING_CMD_PARSER;
|
engine->flags |= I915_ENGINE_USING_CMD_PARSER;
|
||||||
|
|
||||||
|
out:
|
||||||
|
if (intel_engine_requires_cmd_parser(engine) &&
|
||||||
|
!intel_engine_using_cmd_parser(engine))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -1946,7 +1946,7 @@ const char *i915_cache_level_str(struct drm_i915_private *i915, int type);
|
|||||||
|
|
||||||
/* i915_cmd_parser.c */
|
/* i915_cmd_parser.c */
|
||||||
int i915_cmd_parser_get_version(struct drm_i915_private *dev_priv);
|
int i915_cmd_parser_get_version(struct drm_i915_private *dev_priv);
|
||||||
void intel_engine_init_cmd_parser(struct intel_engine_cs *engine);
|
int intel_engine_init_cmd_parser(struct intel_engine_cs *engine);
|
||||||
void intel_engine_cleanup_cmd_parser(struct intel_engine_cs *engine);
|
void intel_engine_cleanup_cmd_parser(struct intel_engine_cs *engine);
|
||||||
int intel_engine_cmd_parser(struct intel_engine_cs *engine,
|
int intel_engine_cmd_parser(struct intel_engine_cs *engine,
|
||||||
struct i915_vma *batch,
|
struct i915_vma *batch,
|
||||||
|
@@ -482,6 +482,16 @@ static int meson_probe_remote(struct platform_device *pdev,
|
|||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void meson_drv_shutdown(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
struct meson_drm *priv = dev_get_drvdata(&pdev->dev);
|
||||||
|
struct drm_device *drm = priv->drm;
|
||||||
|
|
||||||
|
DRM_DEBUG_DRIVER("\n");
|
||||||
|
drm_kms_helper_poll_fini(drm);
|
||||||
|
drm_atomic_helper_shutdown(drm);
|
||||||
|
}
|
||||||
|
|
||||||
static int meson_drv_probe(struct platform_device *pdev)
|
static int meson_drv_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct component_match *match = NULL;
|
struct component_match *match = NULL;
|
||||||
@@ -553,6 +563,7 @@ static const struct dev_pm_ops meson_drv_pm_ops = {
|
|||||||
|
|
||||||
static struct platform_driver meson_drm_platform_driver = {
|
static struct platform_driver meson_drm_platform_driver = {
|
||||||
.probe = meson_drv_probe,
|
.probe = meson_drv_probe,
|
||||||
|
.shutdown = meson_drv_shutdown,
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = "meson-drm",
|
.name = "meson-drm",
|
||||||
.of_match_table = dt_match,
|
.of_match_table = dt_match,
|
||||||
|
@@ -327,6 +327,7 @@ static void qxl_crtc_update_monitors_config(struct drm_crtc *crtc,
|
|||||||
|
|
||||||
head.id = i;
|
head.id = i;
|
||||||
head.flags = 0;
|
head.flags = 0;
|
||||||
|
head.surface_id = 0;
|
||||||
oldcount = qdev->monitors_config->count;
|
oldcount = qdev->monitors_config->count;
|
||||||
if (crtc->state->active) {
|
if (crtc->state->active) {
|
||||||
struct drm_display_mode *mode = &crtc->mode;
|
struct drm_display_mode *mode = &crtc->mode;
|
||||||
|
@@ -83,6 +83,7 @@ MODULE_PARM_DESC(eco_mode, "Turn on Eco mode (less bright, more silent)");
|
|||||||
|
|
||||||
struct gm12u320_device {
|
struct gm12u320_device {
|
||||||
struct drm_device dev;
|
struct drm_device dev;
|
||||||
|
struct device *dmadev;
|
||||||
struct drm_simple_display_pipe pipe;
|
struct drm_simple_display_pipe pipe;
|
||||||
struct drm_connector conn;
|
struct drm_connector conn;
|
||||||
struct usb_device *udev;
|
struct usb_device *udev;
|
||||||
@@ -598,6 +599,22 @@ static const uint64_t gm12u320_pipe_modifiers[] = {
|
|||||||
DRM_FORMAT_MOD_INVALID
|
DRM_FORMAT_MOD_INVALID
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* FIXME: Dma-buf sharing requires DMA support by the importing device.
|
||||||
|
* This function is a workaround to make USB devices work as well.
|
||||||
|
* See todo.rst for how to fix the issue in the dma-buf framework.
|
||||||
|
*/
|
||||||
|
static struct drm_gem_object *gm12u320_gem_prime_import(struct drm_device *dev,
|
||||||
|
struct dma_buf *dma_buf)
|
||||||
|
{
|
||||||
|
struct gm12u320_device *gm12u320 = to_gm12u320(dev);
|
||||||
|
|
||||||
|
if (!gm12u320->dmadev)
|
||||||
|
return ERR_PTR(-ENODEV);
|
||||||
|
|
||||||
|
return drm_gem_prime_import_dev(dev, dma_buf, gm12u320->dmadev);
|
||||||
|
}
|
||||||
|
|
||||||
DEFINE_DRM_GEM_FOPS(gm12u320_fops);
|
DEFINE_DRM_GEM_FOPS(gm12u320_fops);
|
||||||
|
|
||||||
static struct drm_driver gm12u320_drm_driver = {
|
static struct drm_driver gm12u320_drm_driver = {
|
||||||
@@ -611,6 +628,7 @@ static struct drm_driver gm12u320_drm_driver = {
|
|||||||
|
|
||||||
.fops = &gm12u320_fops,
|
.fops = &gm12u320_fops,
|
||||||
DRM_GEM_SHMEM_DRIVER_OPS,
|
DRM_GEM_SHMEM_DRIVER_OPS,
|
||||||
|
.gem_prime_import = gm12u320_gem_prime_import,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct drm_mode_config_funcs gm12u320_mode_config_funcs = {
|
static const struct drm_mode_config_funcs gm12u320_mode_config_funcs = {
|
||||||
@@ -637,16 +655,19 @@ static int gm12u320_usb_probe(struct usb_interface *interface,
|
|||||||
struct gm12u320_device, dev);
|
struct gm12u320_device, dev);
|
||||||
if (IS_ERR(gm12u320))
|
if (IS_ERR(gm12u320))
|
||||||
return PTR_ERR(gm12u320);
|
return PTR_ERR(gm12u320);
|
||||||
|
dev = &gm12u320->dev;
|
||||||
|
|
||||||
|
gm12u320->dmadev = usb_intf_get_dma_device(to_usb_interface(dev->dev));
|
||||||
|
if (!gm12u320->dmadev)
|
||||||
|
drm_warn(dev, "buffer sharing not supported"); /* not an error */
|
||||||
|
|
||||||
gm12u320->udev = interface_to_usbdev(interface);
|
gm12u320->udev = interface_to_usbdev(interface);
|
||||||
INIT_DELAYED_WORK(&gm12u320->fb_update.work, gm12u320_fb_update_work);
|
INIT_DELAYED_WORK(&gm12u320->fb_update.work, gm12u320_fb_update_work);
|
||||||
mutex_init(&gm12u320->fb_update.lock);
|
mutex_init(&gm12u320->fb_update.lock);
|
||||||
|
|
||||||
dev = &gm12u320->dev;
|
|
||||||
|
|
||||||
ret = drmm_mode_config_init(dev);
|
ret = drmm_mode_config_init(dev);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
goto err_put_device;
|
||||||
|
|
||||||
dev->mode_config.min_width = GM12U320_USER_WIDTH;
|
dev->mode_config.min_width = GM12U320_USER_WIDTH;
|
||||||
dev->mode_config.max_width = GM12U320_USER_WIDTH;
|
dev->mode_config.max_width = GM12U320_USER_WIDTH;
|
||||||
@@ -656,15 +677,15 @@ static int gm12u320_usb_probe(struct usb_interface *interface,
|
|||||||
|
|
||||||
ret = gm12u320_usb_alloc(gm12u320);
|
ret = gm12u320_usb_alloc(gm12u320);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
goto err_put_device;
|
||||||
|
|
||||||
ret = gm12u320_set_ecomode(gm12u320);
|
ret = gm12u320_set_ecomode(gm12u320);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
goto err_put_device;
|
||||||
|
|
||||||
ret = gm12u320_conn_init(gm12u320);
|
ret = gm12u320_conn_init(gm12u320);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
goto err_put_device;
|
||||||
|
|
||||||
ret = drm_simple_display_pipe_init(&gm12u320->dev,
|
ret = drm_simple_display_pipe_init(&gm12u320->dev,
|
||||||
&gm12u320->pipe,
|
&gm12u320->pipe,
|
||||||
@@ -674,24 +695,31 @@ static int gm12u320_usb_probe(struct usb_interface *interface,
|
|||||||
gm12u320_pipe_modifiers,
|
gm12u320_pipe_modifiers,
|
||||||
&gm12u320->conn);
|
&gm12u320->conn);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
goto err_put_device;
|
||||||
|
|
||||||
drm_mode_config_reset(dev);
|
drm_mode_config_reset(dev);
|
||||||
|
|
||||||
usb_set_intfdata(interface, dev);
|
usb_set_intfdata(interface, dev);
|
||||||
ret = drm_dev_register(dev, 0);
|
ret = drm_dev_register(dev, 0);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
goto err_put_device;
|
||||||
|
|
||||||
drm_fbdev_generic_setup(dev, 0);
|
drm_fbdev_generic_setup(dev, 0);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
err_put_device:
|
||||||
|
put_device(gm12u320->dmadev);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gm12u320_usb_disconnect(struct usb_interface *interface)
|
static void gm12u320_usb_disconnect(struct usb_interface *interface)
|
||||||
{
|
{
|
||||||
struct drm_device *dev = usb_get_intfdata(interface);
|
struct drm_device *dev = usb_get_intfdata(interface);
|
||||||
|
struct gm12u320_device *gm12u320 = to_gm12u320(dev);
|
||||||
|
|
||||||
|
put_device(gm12u320->dmadev);
|
||||||
|
gm12u320->dmadev = NULL;
|
||||||
drm_dev_unplug(dev);
|
drm_dev_unplug(dev);
|
||||||
drm_atomic_helper_shutdown(dev);
|
drm_atomic_helper_shutdown(dev);
|
||||||
}
|
}
|
||||||
|
@@ -32,6 +32,22 @@ static int udl_usb_resume(struct usb_interface *interface)
|
|||||||
return drm_mode_config_helper_resume(dev);
|
return drm_mode_config_helper_resume(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* FIXME: Dma-buf sharing requires DMA support by the importing device.
|
||||||
|
* This function is a workaround to make USB devices work as well.
|
||||||
|
* See todo.rst for how to fix the issue in the dma-buf framework.
|
||||||
|
*/
|
||||||
|
static struct drm_gem_object *udl_driver_gem_prime_import(struct drm_device *dev,
|
||||||
|
struct dma_buf *dma_buf)
|
||||||
|
{
|
||||||
|
struct udl_device *udl = to_udl(dev);
|
||||||
|
|
||||||
|
if (!udl->dmadev)
|
||||||
|
return ERR_PTR(-ENODEV);
|
||||||
|
|
||||||
|
return drm_gem_prime_import_dev(dev, dma_buf, udl->dmadev);
|
||||||
|
}
|
||||||
|
|
||||||
DEFINE_DRM_GEM_FOPS(udl_driver_fops);
|
DEFINE_DRM_GEM_FOPS(udl_driver_fops);
|
||||||
|
|
||||||
static struct drm_driver driver = {
|
static struct drm_driver driver = {
|
||||||
@@ -42,6 +58,7 @@ static struct drm_driver driver = {
|
|||||||
|
|
||||||
.fops = &udl_driver_fops,
|
.fops = &udl_driver_fops,
|
||||||
DRM_GEM_SHMEM_DRIVER_OPS,
|
DRM_GEM_SHMEM_DRIVER_OPS,
|
||||||
|
.gem_prime_import = udl_driver_gem_prime_import,
|
||||||
|
|
||||||
.name = DRIVER_NAME,
|
.name = DRIVER_NAME,
|
||||||
.desc = DRIVER_DESC,
|
.desc = DRIVER_DESC,
|
||||||
|
@@ -50,6 +50,7 @@ struct urb_list {
|
|||||||
struct udl_device {
|
struct udl_device {
|
||||||
struct drm_device drm;
|
struct drm_device drm;
|
||||||
struct device *dev;
|
struct device *dev;
|
||||||
|
struct device *dmadev;
|
||||||
struct usb_device *udev;
|
struct usb_device *udev;
|
||||||
|
|
||||||
struct drm_simple_display_pipe display_pipe;
|
struct drm_simple_display_pipe display_pipe;
|
||||||
|
@@ -314,6 +314,10 @@ int udl_init(struct udl_device *udl)
|
|||||||
|
|
||||||
DRM_DEBUG("\n");
|
DRM_DEBUG("\n");
|
||||||
|
|
||||||
|
udl->dmadev = usb_intf_get_dma_device(to_usb_interface(dev->dev));
|
||||||
|
if (!udl->dmadev)
|
||||||
|
drm_warn(dev, "buffer sharing not supported"); /* not an error */
|
||||||
|
|
||||||
mutex_init(&udl->gem_lock);
|
mutex_init(&udl->gem_lock);
|
||||||
|
|
||||||
if (!udl_parse_vendor_descriptor(dev, udl->udev)) {
|
if (!udl_parse_vendor_descriptor(dev, udl->udev)) {
|
||||||
@@ -342,12 +346,18 @@ int udl_init(struct udl_device *udl)
|
|||||||
err:
|
err:
|
||||||
if (udl->urbs.count)
|
if (udl->urbs.count)
|
||||||
udl_free_urb_list(dev);
|
udl_free_urb_list(dev);
|
||||||
|
put_device(udl->dmadev);
|
||||||
DRM_ERROR("%d\n", ret);
|
DRM_ERROR("%d\n", ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int udl_drop_usb(struct drm_device *dev)
|
int udl_drop_usb(struct drm_device *dev)
|
||||||
{
|
{
|
||||||
|
struct udl_device *udl = to_udl(dev);
|
||||||
|
|
||||||
udl_free_urb_list(dev);
|
udl_free_urb_list(dev);
|
||||||
|
put_device(udl->dmadev);
|
||||||
|
udl->dmadev = NULL;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@@ -995,7 +995,12 @@ static void logi_hidpp_recv_queue_notif(struct hid_device *hdev,
|
|||||||
workitem.reports_supported |= STD_KEYBOARD;
|
workitem.reports_supported |= STD_KEYBOARD;
|
||||||
break;
|
break;
|
||||||
case 0x0d:
|
case 0x0d:
|
||||||
device_type = "eQUAD Lightspeed 1_1";
|
device_type = "eQUAD Lightspeed 1.1";
|
||||||
|
logi_hidpp_dev_conn_notif_equad(hdev, hidpp_report, &workitem);
|
||||||
|
workitem.reports_supported |= STD_KEYBOARD;
|
||||||
|
break;
|
||||||
|
case 0x0f:
|
||||||
|
device_type = "eQUAD Lightspeed 1.2";
|
||||||
logi_hidpp_dev_conn_notif_equad(hdev, hidpp_report, &workitem);
|
logi_hidpp_dev_conn_notif_equad(hdev, hidpp_report, &workitem);
|
||||||
workitem.reports_supported |= STD_KEYBOARD;
|
workitem.reports_supported |= STD_KEYBOARD;
|
||||||
break;
|
break;
|
||||||
|
@@ -91,7 +91,6 @@
|
|||||||
|
|
||||||
#define RCAR_BUS_PHASE_START (MDBS | MIE | ESG)
|
#define RCAR_BUS_PHASE_START (MDBS | MIE | ESG)
|
||||||
#define RCAR_BUS_PHASE_DATA (MDBS | MIE)
|
#define RCAR_BUS_PHASE_DATA (MDBS | MIE)
|
||||||
#define RCAR_BUS_MASK_DATA (~(ESG | FSB) & 0xFF)
|
|
||||||
#define RCAR_BUS_PHASE_STOP (MDBS | MIE | FSB)
|
#define RCAR_BUS_PHASE_STOP (MDBS | MIE | FSB)
|
||||||
|
|
||||||
#define RCAR_IRQ_SEND (MNR | MAL | MST | MAT | MDE)
|
#define RCAR_IRQ_SEND (MNR | MAL | MST | MAT | MDE)
|
||||||
@@ -120,6 +119,7 @@ enum rcar_i2c_type {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct rcar_i2c_priv {
|
struct rcar_i2c_priv {
|
||||||
|
u32 flags;
|
||||||
void __iomem *io;
|
void __iomem *io;
|
||||||
struct i2c_adapter adap;
|
struct i2c_adapter adap;
|
||||||
struct i2c_msg *msg;
|
struct i2c_msg *msg;
|
||||||
@@ -130,7 +130,6 @@ struct rcar_i2c_priv {
|
|||||||
|
|
||||||
int pos;
|
int pos;
|
||||||
u32 icccr;
|
u32 icccr;
|
||||||
u32 flags;
|
|
||||||
u8 recovery_icmcr; /* protected by adapter lock */
|
u8 recovery_icmcr; /* protected by adapter lock */
|
||||||
enum rcar_i2c_type devtype;
|
enum rcar_i2c_type devtype;
|
||||||
struct i2c_client *slave;
|
struct i2c_client *slave;
|
||||||
@@ -621,7 +620,7 @@ static bool rcar_i2c_slave_irq(struct rcar_i2c_priv *priv)
|
|||||||
/*
|
/*
|
||||||
* This driver has a lock-free design because there are IP cores (at least
|
* This driver has a lock-free design because there are IP cores (at least
|
||||||
* R-Car Gen2) which have an inherent race condition in their hardware design.
|
* R-Car Gen2) which have an inherent race condition in their hardware design.
|
||||||
* There, we need to clear RCAR_BUS_MASK_DATA bits as soon as possible after
|
* There, we need to switch to RCAR_BUS_PHASE_DATA as soon as possible after
|
||||||
* the interrupt was generated, otherwise an unwanted repeated message gets
|
* the interrupt was generated, otherwise an unwanted repeated message gets
|
||||||
* generated. It turned out that taking a spinlock at the beginning of the ISR
|
* generated. It turned out that taking a spinlock at the beginning of the ISR
|
||||||
* was already causing repeated messages. Thus, this driver was converted to
|
* was already causing repeated messages. Thus, this driver was converted to
|
||||||
@@ -630,13 +629,11 @@ static bool rcar_i2c_slave_irq(struct rcar_i2c_priv *priv)
|
|||||||
static irqreturn_t rcar_i2c_irq(int irq, void *ptr)
|
static irqreturn_t rcar_i2c_irq(int irq, void *ptr)
|
||||||
{
|
{
|
||||||
struct rcar_i2c_priv *priv = ptr;
|
struct rcar_i2c_priv *priv = ptr;
|
||||||
u32 msr, val;
|
u32 msr;
|
||||||
|
|
||||||
/* Clear START or STOP immediately, except for REPSTART after read */
|
/* Clear START or STOP immediately, except for REPSTART after read */
|
||||||
if (likely(!(priv->flags & ID_P_REP_AFTER_RD))) {
|
if (likely(!(priv->flags & ID_P_REP_AFTER_RD)))
|
||||||
val = rcar_i2c_read(priv, ICMCR);
|
rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_DATA);
|
||||||
rcar_i2c_write(priv, ICMCR, val & RCAR_BUS_MASK_DATA);
|
|
||||||
}
|
|
||||||
|
|
||||||
msr = rcar_i2c_read(priv, ICMSR);
|
msr = rcar_i2c_read(priv, ICMSR);
|
||||||
|
|
||||||
|
@@ -220,10 +220,10 @@ struct ib_umem *ib_umem_get(struct ib_device *device, unsigned long addr,
|
|||||||
|
|
||||||
cur_base += ret * PAGE_SIZE;
|
cur_base += ret * PAGE_SIZE;
|
||||||
npages -= ret;
|
npages -= ret;
|
||||||
sg = __sg_alloc_table_from_pages(
|
sg = __sg_alloc_table_from_pages(&umem->sg_head, page_list, ret,
|
||||||
&umem->sg_head, page_list, ret, 0, ret << PAGE_SHIFT,
|
0, ret << PAGE_SHIFT,
|
||||||
dma_get_max_seg_size(device->dma_device), sg, npages,
|
ib_dma_max_seg_size(device), sg, npages,
|
||||||
GFP_KERNEL);
|
GFP_KERNEL);
|
||||||
umem->sg_nents = umem->sg_head.nents;
|
umem->sg_nents = umem->sg_head.nents;
|
||||||
if (IS_ERR(sg)) {
|
if (IS_ERR(sg)) {
|
||||||
unpin_user_pages_dirty_lock(page_list, ret, 0);
|
unpin_user_pages_dirty_lock(page_list, ret, 0);
|
||||||
|
@@ -48,6 +48,7 @@
|
|||||||
#include <linux/efi.h>
|
#include <linux/efi.h>
|
||||||
#include <linux/input.h>
|
#include <linux/input.h>
|
||||||
#include <linux/input/mt.h>
|
#include <linux/input/mt.h>
|
||||||
|
#include <linux/ktime.h>
|
||||||
#include <linux/leds.h>
|
#include <linux/leds.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/spinlock.h>
|
#include <linux/spinlock.h>
|
||||||
@@ -400,7 +401,7 @@ struct applespi_data {
|
|||||||
unsigned int cmd_msg_cntr;
|
unsigned int cmd_msg_cntr;
|
||||||
/* lock to protect the above parameters and flags below */
|
/* lock to protect the above parameters and flags below */
|
||||||
spinlock_t cmd_msg_lock;
|
spinlock_t cmd_msg_lock;
|
||||||
bool cmd_msg_queued;
|
ktime_t cmd_msg_queued;
|
||||||
enum applespi_evt_type cmd_evt_type;
|
enum applespi_evt_type cmd_evt_type;
|
||||||
|
|
||||||
struct led_classdev backlight_info;
|
struct led_classdev backlight_info;
|
||||||
@@ -716,7 +717,7 @@ static void applespi_msg_complete(struct applespi_data *applespi,
|
|||||||
wake_up_all(&applespi->drain_complete);
|
wake_up_all(&applespi->drain_complete);
|
||||||
|
|
||||||
if (is_write_msg) {
|
if (is_write_msg) {
|
||||||
applespi->cmd_msg_queued = false;
|
applespi->cmd_msg_queued = 0;
|
||||||
applespi_send_cmd_msg(applespi);
|
applespi_send_cmd_msg(applespi);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -758,8 +759,16 @@ static int applespi_send_cmd_msg(struct applespi_data *applespi)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* check whether send is in progress */
|
/* check whether send is in progress */
|
||||||
if (applespi->cmd_msg_queued)
|
if (applespi->cmd_msg_queued) {
|
||||||
return 0;
|
if (ktime_ms_delta(ktime_get(), applespi->cmd_msg_queued) < 1000)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
dev_warn(&applespi->spi->dev, "Command %d timed out\n",
|
||||||
|
applespi->cmd_evt_type);
|
||||||
|
|
||||||
|
applespi->cmd_msg_queued = 0;
|
||||||
|
applespi->write_active = false;
|
||||||
|
}
|
||||||
|
|
||||||
/* set up packet */
|
/* set up packet */
|
||||||
memset(packet, 0, APPLESPI_PACKET_SIZE);
|
memset(packet, 0, APPLESPI_PACKET_SIZE);
|
||||||
@@ -856,7 +865,7 @@ static int applespi_send_cmd_msg(struct applespi_data *applespi)
|
|||||||
return sts;
|
return sts;
|
||||||
}
|
}
|
||||||
|
|
||||||
applespi->cmd_msg_queued = true;
|
applespi->cmd_msg_queued = ktime_get_coarse();
|
||||||
applespi->write_active = true;
|
applespi->write_active = true;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -1908,7 +1917,7 @@ static int __maybe_unused applespi_resume(struct device *dev)
|
|||||||
applespi->drain = false;
|
applespi->drain = false;
|
||||||
applespi->have_cl_led_on = false;
|
applespi->have_cl_led_on = false;
|
||||||
applespi->have_bl_level = 0;
|
applespi->have_bl_level = 0;
|
||||||
applespi->cmd_msg_queued = false;
|
applespi->cmd_msg_queued = 0;
|
||||||
applespi->read_active = false;
|
applespi->read_active = false;
|
||||||
applespi->write_active = false;
|
applespi->write_active = false;
|
||||||
|
|
||||||
|
@@ -12,6 +12,7 @@
|
|||||||
#include <linux/acpi.h>
|
#include <linux/acpi.h>
|
||||||
#include <linux/list.h>
|
#include <linux/list.h>
|
||||||
#include <linux/bitmap.h>
|
#include <linux/bitmap.h>
|
||||||
|
#include <linux/delay.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/syscore_ops.h>
|
#include <linux/syscore_ops.h>
|
||||||
#include <linux/interrupt.h>
|
#include <linux/interrupt.h>
|
||||||
@@ -254,6 +255,8 @@ static enum iommu_init_state init_state = IOMMU_START_STATE;
|
|||||||
static int amd_iommu_enable_interrupts(void);
|
static int amd_iommu_enable_interrupts(void);
|
||||||
static int __init iommu_go_to_state(enum iommu_init_state state);
|
static int __init iommu_go_to_state(enum iommu_init_state state);
|
||||||
static void init_device_table_dma(void);
|
static void init_device_table_dma(void);
|
||||||
|
static int iommu_pc_get_set_reg(struct amd_iommu *iommu, u8 bank, u8 cntr,
|
||||||
|
u8 fxn, u64 *value, bool is_write);
|
||||||
|
|
||||||
static bool amd_iommu_pre_enabled = true;
|
static bool amd_iommu_pre_enabled = true;
|
||||||
|
|
||||||
@@ -1717,13 +1720,11 @@ static int __init init_iommu_all(struct acpi_table_header *table)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int iommu_pc_get_set_reg(struct amd_iommu *iommu, u8 bank, u8 cntr,
|
static void __init init_iommu_perf_ctr(struct amd_iommu *iommu)
|
||||||
u8 fxn, u64 *value, bool is_write);
|
|
||||||
|
|
||||||
static void init_iommu_perf_ctr(struct amd_iommu *iommu)
|
|
||||||
{
|
{
|
||||||
|
int retry;
|
||||||
struct pci_dev *pdev = iommu->dev;
|
struct pci_dev *pdev = iommu->dev;
|
||||||
u64 val = 0xabcd, val2 = 0, save_reg = 0;
|
u64 val = 0xabcd, val2 = 0, save_reg, save_src;
|
||||||
|
|
||||||
if (!iommu_feature(iommu, FEATURE_PC))
|
if (!iommu_feature(iommu, FEATURE_PC))
|
||||||
return;
|
return;
|
||||||
@@ -1731,17 +1732,39 @@ static void init_iommu_perf_ctr(struct amd_iommu *iommu)
|
|||||||
amd_iommu_pc_present = true;
|
amd_iommu_pc_present = true;
|
||||||
|
|
||||||
/* save the value to restore, if writable */
|
/* save the value to restore, if writable */
|
||||||
if (iommu_pc_get_set_reg(iommu, 0, 0, 0, &save_reg, false))
|
if (iommu_pc_get_set_reg(iommu, 0, 0, 0, &save_reg, false) ||
|
||||||
|
iommu_pc_get_set_reg(iommu, 0, 0, 8, &save_src, false))
|
||||||
|
goto pc_false;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Disable power gating by programing the performance counter
|
||||||
|
* source to 20 (i.e. counts the reads and writes from/to IOMMU
|
||||||
|
* Reserved Register [MMIO Offset 1FF8h] that are ignored.),
|
||||||
|
* which never get incremented during this init phase.
|
||||||
|
* (Note: The event is also deprecated.)
|
||||||
|
*/
|
||||||
|
val = 20;
|
||||||
|
if (iommu_pc_get_set_reg(iommu, 0, 0, 8, &val, true))
|
||||||
goto pc_false;
|
goto pc_false;
|
||||||
|
|
||||||
/* Check if the performance counters can be written to */
|
/* Check if the performance counters can be written to */
|
||||||
if ((iommu_pc_get_set_reg(iommu, 0, 0, 0, &val, true)) ||
|
val = 0xabcd;
|
||||||
(iommu_pc_get_set_reg(iommu, 0, 0, 0, &val2, false)) ||
|
for (retry = 5; retry; retry--) {
|
||||||
(val != val2))
|
if (iommu_pc_get_set_reg(iommu, 0, 0, 0, &val, true) ||
|
||||||
goto pc_false;
|
iommu_pc_get_set_reg(iommu, 0, 0, 0, &val2, false) ||
|
||||||
|
val2)
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Wait about 20 msec for power gating to disable and retry. */
|
||||||
|
msleep(20);
|
||||||
|
}
|
||||||
|
|
||||||
/* restore */
|
/* restore */
|
||||||
if (iommu_pc_get_set_reg(iommu, 0, 0, 0, &save_reg, true))
|
if (iommu_pc_get_set_reg(iommu, 0, 0, 0, &save_reg, true) ||
|
||||||
|
iommu_pc_get_set_reg(iommu, 0, 0, 8, &save_src, true))
|
||||||
|
goto pc_false;
|
||||||
|
|
||||||
|
if (val != val2)
|
||||||
goto pc_false;
|
goto pc_false;
|
||||||
|
|
||||||
pci_info(pdev, "IOMMU performance counters supported\n");
|
pci_info(pdev, "IOMMU performance counters supported\n");
|
||||||
|
@@ -1079,8 +1079,17 @@ prq_advance:
|
|||||||
* Clear the page request overflow bit and wake up all threads that
|
* Clear the page request overflow bit and wake up all threads that
|
||||||
* are waiting for the completion of this handling.
|
* are waiting for the completion of this handling.
|
||||||
*/
|
*/
|
||||||
if (readl(iommu->reg + DMAR_PRS_REG) & DMA_PRS_PRO)
|
if (readl(iommu->reg + DMAR_PRS_REG) & DMA_PRS_PRO) {
|
||||||
writel(DMA_PRS_PRO, iommu->reg + DMAR_PRS_REG);
|
pr_info_ratelimited("IOMMU: %s: PRQ overflow detected\n",
|
||||||
|
iommu->name);
|
||||||
|
head = dmar_readq(iommu->reg + DMAR_PQH_REG) & PRQ_RING_MASK;
|
||||||
|
tail = dmar_readq(iommu->reg + DMAR_PQT_REG) & PRQ_RING_MASK;
|
||||||
|
if (head == tail) {
|
||||||
|
writel(DMA_PRS_PRO, iommu->reg + DMAR_PRS_REG);
|
||||||
|
pr_info_ratelimited("IOMMU: %s: PRQ overflow cleared",
|
||||||
|
iommu->name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!completion_done(&iommu->prq_complete))
|
if (!completion_done(&iommu->prq_complete))
|
||||||
complete(&iommu->prq_complete);
|
complete(&iommu->prq_complete);
|
||||||
|
@@ -245,7 +245,7 @@ static int vsp1_du_pipeline_setup_brx(struct vsp1_device *vsp1,
|
|||||||
brx = &vsp1->bru->entity;
|
brx = &vsp1->bru->entity;
|
||||||
else if (pipe->brx && !drm_pipe->force_brx_release)
|
else if (pipe->brx && !drm_pipe->force_brx_release)
|
||||||
brx = pipe->brx;
|
brx = pipe->brx;
|
||||||
else if (!vsp1->bru->entity.pipe)
|
else if (vsp1_feature(vsp1, VSP1_HAS_BRU) && !vsp1->bru->entity.pipe)
|
||||||
brx = &vsp1->bru->entity;
|
brx = &vsp1->bru->entity;
|
||||||
else
|
else
|
||||||
brx = &vsp1->brs->entity;
|
brx = &vsp1->brs->entity;
|
||||||
@@ -462,9 +462,9 @@ static int vsp1_du_pipeline_setup_inputs(struct vsp1_device *vsp1,
|
|||||||
* make sure it is present in the pipeline's list of entities if it
|
* make sure it is present in the pipeline's list of entities if it
|
||||||
* wasn't already.
|
* wasn't already.
|
||||||
*/
|
*/
|
||||||
if (!use_uif) {
|
if (drm_pipe->uif && !use_uif) {
|
||||||
drm_pipe->uif->pipe = NULL;
|
drm_pipe->uif->pipe = NULL;
|
||||||
} else if (!drm_pipe->uif->pipe) {
|
} else if (drm_pipe->uif && !drm_pipe->uif->pipe) {
|
||||||
drm_pipe->uif->pipe = pipe;
|
drm_pipe->uif->pipe = pipe;
|
||||||
list_add_tail(&drm_pipe->uif->list_pipe, &pipe->entities);
|
list_add_tail(&drm_pipe->uif->list_pipe, &pipe->entities);
|
||||||
}
|
}
|
||||||
|
@@ -5,6 +5,7 @@ obj-y += keymaps/
|
|||||||
obj-$(CONFIG_RC_CORE) += rc-core.o
|
obj-$(CONFIG_RC_CORE) += rc-core.o
|
||||||
rc-core-y := rc-main.o rc-ir-raw.o
|
rc-core-y := rc-main.o rc-ir-raw.o
|
||||||
rc-core-$(CONFIG_LIRC) += lirc_dev.o
|
rc-core-$(CONFIG_LIRC) += lirc_dev.o
|
||||||
|
rc-core-$(CONFIG_MEDIA_CEC_RC) += keymaps/rc-cec.o
|
||||||
rc-core-$(CONFIG_BPF_LIRC_MODE2) += bpf-lirc.o
|
rc-core-$(CONFIG_BPF_LIRC_MODE2) += bpf-lirc.o
|
||||||
obj-$(CONFIG_IR_NEC_DECODER) += ir-nec-decoder.o
|
obj-$(CONFIG_IR_NEC_DECODER) += ir-nec-decoder.o
|
||||||
obj-$(CONFIG_IR_RC5_DECODER) += ir-rc5-decoder.o
|
obj-$(CONFIG_IR_RC5_DECODER) += ir-rc5-decoder.o
|
||||||
|
@@ -21,7 +21,6 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \
|
|||||||
rc-behold.o \
|
rc-behold.o \
|
||||||
rc-behold-columbus.o \
|
rc-behold-columbus.o \
|
||||||
rc-budget-ci-old.o \
|
rc-budget-ci-old.o \
|
||||||
rc-cec.o \
|
|
||||||
rc-cinergy-1400.o \
|
rc-cinergy-1400.o \
|
||||||
rc-cinergy.o \
|
rc-cinergy.o \
|
||||||
rc-d680-dmb.o \
|
rc-d680-dmb.o \
|
||||||
|
@@ -1,5 +1,15 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
/* Keytable for the CEC remote control
|
/* Keytable for the CEC remote control
|
||||||
|
*
|
||||||
|
* This keymap is unusual in that it can't be built as a module,
|
||||||
|
* instead it is registered directly in rc-main.c if CONFIG_MEDIA_CEC_RC
|
||||||
|
* is set. This is because it can be called from drm_dp_cec_set_edid() via
|
||||||
|
* cec_register_adapter() in an asynchronous context, and it is not
|
||||||
|
* allowed to use request_module() to load rc-cec.ko in that case.
|
||||||
|
*
|
||||||
|
* Since this keymap is only used if CONFIG_MEDIA_CEC_RC is set, we
|
||||||
|
* just compile this keymap into the rc-core module and never as a
|
||||||
|
* separate module.
|
||||||
*
|
*
|
||||||
* Copyright (c) 2015 by Kamil Debski
|
* Copyright (c) 2015 by Kamil Debski
|
||||||
*/
|
*/
|
||||||
@@ -152,7 +162,7 @@ static struct rc_map_table cec[] = {
|
|||||||
/* 0x77-0xff: Reserved */
|
/* 0x77-0xff: Reserved */
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct rc_map_list cec_map = {
|
struct rc_map_list cec_map = {
|
||||||
.map = {
|
.map = {
|
||||||
.scan = cec,
|
.scan = cec,
|
||||||
.size = ARRAY_SIZE(cec),
|
.size = ARRAY_SIZE(cec),
|
||||||
@@ -160,19 +170,3 @@ static struct rc_map_list cec_map = {
|
|||||||
.name = RC_MAP_CEC,
|
.name = RC_MAP_CEC,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static int __init init_rc_map_cec(void)
|
|
||||||
{
|
|
||||||
return rc_map_register(&cec_map);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __exit exit_rc_map_cec(void)
|
|
||||||
{
|
|
||||||
rc_map_unregister(&cec_map);
|
|
||||||
}
|
|
||||||
|
|
||||||
module_init(init_rc_map_cec);
|
|
||||||
module_exit(exit_rc_map_cec);
|
|
||||||
|
|
||||||
MODULE_LICENSE("GPL");
|
|
||||||
MODULE_AUTHOR("Kamil Debski");
|
|
||||||
|
@@ -2069,6 +2069,9 @@ static int __init rc_core_init(void)
|
|||||||
|
|
||||||
led_trigger_register_simple("rc-feedback", &led_feedback);
|
led_trigger_register_simple("rc-feedback", &led_feedback);
|
||||||
rc_map_register(&empty_map);
|
rc_map_register(&empty_map);
|
||||||
|
#ifdef CONFIG_MEDIA_CEC_RC
|
||||||
|
rc_map_register(&cec_map);
|
||||||
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -2078,6 +2081,9 @@ static void __exit rc_core_exit(void)
|
|||||||
lirc_dev_exit();
|
lirc_dev_exit();
|
||||||
class_unregister(&rc_class);
|
class_unregister(&rc_class);
|
||||||
led_trigger_unregister_simple(led_feedback);
|
led_trigger_unregister_simple(led_feedback);
|
||||||
|
#ifdef CONFIG_MEDIA_CEC_RC
|
||||||
|
rc_map_unregister(&cec_map);
|
||||||
|
#endif
|
||||||
rc_map_unregister(&empty_map);
|
rc_map_unregister(&empty_map);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -371,7 +371,7 @@ void usbtv_audio_free(struct usbtv *usbtv)
|
|||||||
cancel_work_sync(&usbtv->snd_trigger);
|
cancel_work_sync(&usbtv->snd_trigger);
|
||||||
|
|
||||||
if (usbtv->snd && usbtv->udev) {
|
if (usbtv->snd && usbtv->udev) {
|
||||||
snd_card_free(usbtv->snd);
|
snd_card_free_when_closed(usbtv->snd);
|
||||||
usbtv->snd = NULL;
|
usbtv->snd = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -948,6 +948,11 @@ static int fastrpc_internal_invoke(struct fastrpc_user *fl, u32 kernel,
|
|||||||
if (!fl->cctx->rpdev)
|
if (!fl->cctx->rpdev)
|
||||||
return -EPIPE;
|
return -EPIPE;
|
||||||
|
|
||||||
|
if (handle == FASTRPC_INIT_HANDLE && !kernel) {
|
||||||
|
dev_warn_ratelimited(fl->sctx->dev, "user app trying to send a kernel RPC message (%d)\n", handle);
|
||||||
|
return -EPERM;
|
||||||
|
}
|
||||||
|
|
||||||
ctx = fastrpc_context_alloc(fl, kernel, sc, args);
|
ctx = fastrpc_context_alloc(fl, kernel, sc, args);
|
||||||
if (IS_ERR(ctx))
|
if (IS_ERR(ctx))
|
||||||
return PTR_ERR(ctx);
|
return PTR_ERR(ctx);
|
||||||
|
@@ -166,6 +166,7 @@ static const struct of_device_id pvpanic_mmio_match[] = {
|
|||||||
{ .compatible = "qemu,pvpanic-mmio", },
|
{ .compatible = "qemu,pvpanic-mmio", },
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
MODULE_DEVICE_TABLE(of, pvpanic_mmio_match);
|
||||||
|
|
||||||
static struct platform_driver pvpanic_mmio_driver = {
|
static struct platform_driver pvpanic_mmio_driver = {
|
||||||
.driver = {
|
.driver = {
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user